From bfc6edc1dde18f4acc825ccfb397cdfebd99de31 Mon Sep 17 00:00:00 2001 From: Suha Can Date: Mon, 10 May 2010 13:35:07 -0700 Subject: [PATCH] - An autofac events module for dynamic proxy creation when an interface of type IEventHandler is resolved through DI. - Intercept method on the proxy calls Notify on the event-bus with appropriate conversion of event name and parameters. --HG-- branch : dev --- src/Orchard/Events/EventsInterceptor.cs | 23 ++++++++++ src/Orchard/Events/EventsModule.cs | 10 +++++ .../Events/EventsRegistrationSource.cs | 43 +++++++++++++++++++ src/Orchard/Events/IEventHandler.cs | 4 ++ src/Orchard/Orchard.Framework.csproj | 4 ++ 5 files changed, 84 insertions(+) create mode 100644 src/Orchard/Events/EventsInterceptor.cs create mode 100644 src/Orchard/Events/EventsModule.cs create mode 100644 src/Orchard/Events/EventsRegistrationSource.cs create mode 100644 src/Orchard/Events/IEventHandler.cs diff --git a/src/Orchard/Events/EventsInterceptor.cs b/src/Orchard/Events/EventsInterceptor.cs new file mode 100644 index 000000000..0c71265fe --- /dev/null +++ b/src/Orchard/Events/EventsInterceptor.cs @@ -0,0 +1,23 @@ +using System.Linq; +using Castle.Core.Interceptor; + +namespace Orchard.Events { + public class EventsInterceptor : IInterceptor { + private readonly IEventBus _eventBus; + + public EventsInterceptor(IEventBus eventBus) { + _eventBus = eventBus; + } + + public void Intercept(IInvocation invocation) { + var interfaceName = invocation.Method.DeclaringType.Name; + var methodName = invocation.Method.Name; + + var data = invocation.Method.GetParameters() + .Select((parameter, index) => new { parameter.Name, Value = invocation.Arguments[index] }) + .ToDictionary(kv => kv.Name, kv => kv.Value.ToString()); + + _eventBus.Notify(interfaceName + "_" + methodName, data); + } + } +} diff --git a/src/Orchard/Events/EventsModule.cs b/src/Orchard/Events/EventsModule.cs new file mode 100644 index 000000000..2aa10ef52 --- /dev/null +++ b/src/Orchard/Events/EventsModule.cs @@ -0,0 +1,10 @@ +using Autofac; + +namespace Orchard.Events { + public class EventsModule : Module { + protected override void Load(ContainerBuilder builder) { + builder.RegisterSource(new EventsRegistrationSource()); + base.Load(builder); + } + } +} diff --git a/src/Orchard/Events/EventsRegistrationSource.cs b/src/Orchard/Events/EventsRegistrationSource.cs new file mode 100644 index 000000000..e39d7fe51 --- /dev/null +++ b/src/Orchard/Events/EventsRegistrationSource.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using Autofac; +using Autofac.Builder; +using Autofac.Core; +using Castle.Core.Interceptor; +using Castle.DynamicProxy; + +namespace Orchard.Events { + public class EventsRegistrationSource : IRegistrationSource { + private readonly DefaultProxyBuilder _proxyBuilder; + + public EventsRegistrationSource() { + _proxyBuilder = new DefaultProxyBuilder(); + } + + public IEnumerable RegistrationsFor(Service service, Func> registrationAccessor) { + var serviceWithType = service as IServiceWithType; + if (serviceWithType == null) + yield break; + + var serviceType = serviceWithType.ServiceType; + if (!serviceType.IsInterface || !typeof(IEventHandler).IsAssignableFrom(serviceType)) + yield break; + + var interfaceProxyType = _proxyBuilder.CreateInterfaceProxyTypeWithoutTarget( + serviceType, + new Type[0], + ProxyGenerationOptions.Default); + + + var rb = RegistrationBuilder + .ForDelegate((ctx, parameters) => { + var interceptors = new IInterceptor[] { new EventsInterceptor(ctx.Resolve()) }; + var args = new object[] { interceptors, null }; + return Activator.CreateInstance(interfaceProxyType, args); + }) + .As(service); + + yield return rb.CreateRegistration(); + } + } +} \ No newline at end of file diff --git a/src/Orchard/Events/IEventHandler.cs b/src/Orchard/Events/IEventHandler.cs new file mode 100644 index 000000000..b40f7ae9a --- /dev/null +++ b/src/Orchard/Events/IEventHandler.cs @@ -0,0 +1,4 @@ +namespace Orchard.Events { + public interface IEventHandler { + } +} diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index 9beecc61b..0a8653d58 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -181,6 +181,9 @@ + + + @@ -190,6 +193,7 @@ +