From 80007a51019cc1d5568ac26268c324dd3cf1bf0b Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Wed, 7 Apr 2010 13:30:18 -0700 Subject: [PATCH] Allowing modules to add interceptors to registered components Removes reference to Autofac contrib dynamicproxy assembly Shell factories enable dynamic proxy as dependencies are registered CurrentUser and CurrentSite interceptors updated for new api Castle.DynamicProxy2 v2.1 is used to avoid rebuilding nhib binaries --HG-- branch : dev --- .../Setup/SetupControllerTests.cs | 2 +- .../ContentPartDriverHandlerTests.cs | 2 +- .../DynamicProxy2/DynamicProxyTests.cs | 141 ++++++++++++++++++ .../Environment/DefaultOrchardHostTests.cs | 2 +- src/Orchard.Tests/Orchard.Tests.csproj | 9 ++ .../ContainerUpdater.cs | 4 +- .../DynamicProxy2/ConstructorFinderWrapper.cs | 25 ++++ .../DynamicProxy2/DynamicProxyContext.cs | 97 ++++++++++++ .../DynamicProxy2/DynamicProxyExtensions.cs | 35 +++++ .../ExtensibleInterceptionModule.cs | 28 ---- .../Environment/FiniteContainerProvider.cs | 2 +- src/Orchard/Environment/OrchardStarter.cs | 1 + .../DefaultShellContainerFactory.cs | 7 +- .../SafeModeShellContainerFactory.cs | 7 +- src/Orchard/Mvc/MvcModule.cs | 6 +- src/Orchard/Orchard.csproj | 14 +- src/Orchard/Security/SecurityModule.cs | 49 +++--- src/Orchard/Settings/SettingsModule.cs | 42 +++--- 18 files changed, 376 insertions(+), 97 deletions(-) create mode 100644 src/Orchard.Tests/Environment/AutofacUtil/DynamicProxy2/DynamicProxyTests.cs rename src/Orchard/Environment/{ShellBuilders => AutofacUtil}/ContainerUpdater.cs (77%) create mode 100644 src/Orchard/Environment/AutofacUtil/DynamicProxy2/ConstructorFinderWrapper.cs create mode 100644 src/Orchard/Environment/AutofacUtil/DynamicProxy2/DynamicProxyContext.cs create mode 100644 src/Orchard/Environment/AutofacUtil/DynamicProxy2/DynamicProxyExtensions.cs delete mode 100644 src/Orchard/Environment/ExtensibleInterceptionModule.cs diff --git a/src/Orchard.Tests.Modules/Setup/SetupControllerTests.cs b/src/Orchard.Tests.Modules/Setup/SetupControllerTests.cs index 2f498e37c..372bbb731 100644 --- a/src/Orchard.Tests.Modules/Setup/SetupControllerTests.cs +++ b/src/Orchard.Tests.Modules/Setup/SetupControllerTests.cs @@ -5,8 +5,8 @@ using System.Web.Routing; using Autofac; using NUnit.Framework; using Orchard.Environment; +using Orchard.Environment.AutofacUtil; using Orchard.Environment.Configuration; -using Orchard.Environment.ShellBuilders; using Orchard.Setup.Controllers; using Orchard.Setup.ViewModels; using Orchard.UI.Notify; diff --git a/src/Orchard.Tests/ContentManagement/ContentPartDriverHandlerTests.cs b/src/Orchard.Tests/ContentManagement/ContentPartDriverHandlerTests.cs index 47b8232e4..75a6fd49f 100644 --- a/src/Orchard.Tests/ContentManagement/ContentPartDriverHandlerTests.cs +++ b/src/Orchard.Tests/ContentManagement/ContentPartDriverHandlerTests.cs @@ -6,7 +6,7 @@ using NUnit.Framework; using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; using Orchard.ContentManagement.Handlers; -using Orchard.Environment.ShellBuilders; +using Orchard.Environment.AutofacUtil; using Orchard.Mvc.ViewModels; using Orchard.UI.Zones; diff --git a/src/Orchard.Tests/Environment/AutofacUtil/DynamicProxy2/DynamicProxyTests.cs b/src/Orchard.Tests/Environment/AutofacUtil/DynamicProxy2/DynamicProxyTests.cs new file mode 100644 index 000000000..5971db565 --- /dev/null +++ b/src/Orchard.Tests/Environment/AutofacUtil/DynamicProxy2/DynamicProxyTests.cs @@ -0,0 +1,141 @@ +using System; +using Autofac; +using Autofac.Core; +using Autofac.Features.Metadata; +using Castle.Core.Interceptor; +using NUnit.Framework; +using Orchard.Environment.AutofacUtil.DynamicProxy2; + +namespace Orchard.Tests.Environment.AutofacUtil.DynamicProxy2 { + [TestFixture] + public class DynamicProxyTests { + [Test] + public void ContextAddedToMetadataWhenRegistered() { + var context = new DynamicProxyContext(); + + var builder = new ContainerBuilder(); + builder.RegisterType().EnableDynamicProxy(context); + + var container = builder.Build(); + + var meta = container.Resolve>(); + Assert.That(meta.Metadata, Has.Some.Property("Key").EqualTo("Orchard.Environment.AutofacUtil.DynamicProxy2.DynamicProxyContext.ProxyContextKey")); + Assert.That(meta.Metadata["Orchard.Environment.AutofacUtil.DynamicProxy2.DynamicProxyContext.ProxyContextKey"], Is.SameAs(context)); + } + + [Test] + public void ProxyContextReturnsTrueIfTypeHasBeenProxied() { + var context = new DynamicProxyContext(); + + Type proxyType; + Assert.That(context.TryGetProxy(typeof(SimpleComponent), out proxyType), Is.False); + Assert.That(context.TryGetProxy(typeof(SimpleComponent), out proxyType), Is.False); + Assert.That(proxyType, Is.Null); + + context.AddProxy(typeof(SimpleComponent)); + Assert.That(context.TryGetProxy(typeof(SimpleComponent), out proxyType), Is.True); + Assert.That(context.TryGetProxy(typeof(SimpleComponent), out proxyType), Is.True); + Assert.That(proxyType, Is.Not.Null); + } + + [Test] + public void AddProxyCanBeCalledMoreThanOnce() { + var context = new DynamicProxyContext(); + context.AddProxy(typeof(SimpleComponent)); + + Type proxyType; + Assert.That(context.TryGetProxy(typeof(SimpleComponent), out proxyType), Is.True); + Assert.That(proxyType, Is.Not.Null); + + Type proxyType2; + context.AddProxy(typeof(SimpleComponent)); + Assert.That(context.TryGetProxy(typeof(SimpleComponent), out proxyType2), Is.True); + + Assert.That(proxyType2, Is.SameAs(proxyType)); + } + + [Test] + public void InterceptorAddedToContextFromModules() { + var context = new DynamicProxyContext(); + + var builder = new ContainerBuilder(); + builder.RegisterType().EnableDynamicProxy(context); + builder.RegisterModule(new SimpleInterceptorModule()); + + builder.Build(); + + Type proxyType; + Assert.That(context.TryGetProxy(typeof(SimpleComponent), out proxyType), Is.True); + Assert.That(proxyType, Is.Not.Null); + } + + [Test] + public void ResolvedObjectIsSubclass() { + var context = new DynamicProxyContext(); + + var builder = new ContainerBuilder(); + builder.RegisterType().EnableDynamicProxy(context); + builder.RegisterModule(new SimpleInterceptorModule()); + + var container = builder.Build(); + + var simpleComponent = container.Resolve(); + Assert.That(simpleComponent, Is.InstanceOf()); + Assert.That(simpleComponent, Is.Not.TypeOf()); + } + + [Test] + public void InterceptorCatchesMethodCallOnlyFromContainerWithInterceptor() { + var context = new DynamicProxyContext(); + + var builder1 = new ContainerBuilder(); + builder1.RegisterType().EnableDynamicProxy(context); + builder1.RegisterModule(new SimpleInterceptorModule()); + var container1 = builder1.Build(); + + var simple1 = container1.Resolve(); + + var builder2 = new ContainerBuilder(); + builder2.RegisterType().EnableDynamicProxy(context); + var container2 = builder2.Build(); + + var simple2 = container2.Resolve(); + + Assert.That(simple2.SimpleMethod(), Is.EqualTo("default return value")); + Assert.That(simple1.SimpleMethod(), Is.EqualTo("different return value")); + } + } + + public class SimpleComponent { + public virtual string SimpleMethod() { + return "default return value"; + } + } + + public class SimpleInterceptorModule : Module { + protected override void Load(ContainerBuilder builder) { + builder.RegisterType(); + + base.Load(builder); + } + + protected override void AttachToComponentRegistration( + IComponentRegistry componentRegistry, + IComponentRegistration registration) { + + if (DynamicProxyContext.From(registration) != null) + registration.InterceptedBy(); + } + } + + public class SimpleInterceptor : IInterceptor { + public void Intercept(IInvocation invocation) { + if (invocation.Method.Name == "SimpleMethod") { + invocation.ReturnValue = "different return value"; + } + else { + invocation.Proceed(); + } + } + } +} diff --git a/src/Orchard.Tests/Environment/DefaultOrchardHostTests.cs b/src/Orchard.Tests/Environment/DefaultOrchardHostTests.cs index 76b37cfc5..3e201b0ec 100644 --- a/src/Orchard.Tests/Environment/DefaultOrchardHostTests.cs +++ b/src/Orchard.Tests/Environment/DefaultOrchardHostTests.cs @@ -9,8 +9,8 @@ using Autofac.Integration.Web; using Moq; using NUnit.Framework; using Orchard.Environment; +using Orchard.Environment.AutofacUtil; using Orchard.Environment.Configuration; -using Orchard.Environment.ShellBuilders; using Orchard.Mvc; using Orchard.Mvc.ModelBinders; using Orchard.Mvc.Routes; diff --git a/src/Orchard.Tests/Orchard.Tests.csproj b/src/Orchard.Tests/Orchard.Tests.csproj index 55c3553d3..22e917d4a 100644 --- a/src/Orchard.Tests/Orchard.Tests.csproj +++ b/src/Orchard.Tests/Orchard.Tests.csproj @@ -43,6 +43,14 @@ False ..\..\lib\autofac\Autofac.Integration.Web.Mvc.dll + + False + ..\..\lib\Castle Windsor 2.0\bin\Castle.Core.dll + + + False + ..\..\lib\Castle Windsor 2.0\bin\Castle.DynamicProxy2.dll + False ..\..\lib\fluentnhibernate\FluentNHibernate.dll @@ -143,6 +151,7 @@ + diff --git a/src/Orchard/Environment/ShellBuilders/ContainerUpdater.cs b/src/Orchard/Environment/AutofacUtil/ContainerUpdater.cs similarity index 77% rename from src/Orchard/Environment/ShellBuilders/ContainerUpdater.cs rename to src/Orchard/Environment/AutofacUtil/ContainerUpdater.cs index d3d63eb4f..4ebf29bae 100644 --- a/src/Orchard/Environment/ShellBuilders/ContainerUpdater.cs +++ b/src/Orchard/Environment/AutofacUtil/ContainerUpdater.cs @@ -3,9 +3,9 @@ using System.Collections.Generic; using Autofac; using Autofac.Core; -namespace Orchard.Environment.ShellBuilders { +namespace Orchard.Environment.AutofacUtil { public class ContainerUpdater : ContainerBuilder { - ICollection> _configurationActions = new List>(); + readonly ICollection> _configurationActions = new List>(); public override void RegisterCallback(Action configurationAction) { _configurationActions.Add(configurationAction); diff --git a/src/Orchard/Environment/AutofacUtil/DynamicProxy2/ConstructorFinderWrapper.cs b/src/Orchard/Environment/AutofacUtil/DynamicProxy2/ConstructorFinderWrapper.cs new file mode 100644 index 000000000..a4f37df3a --- /dev/null +++ b/src/Orchard/Environment/AutofacUtil/DynamicProxy2/ConstructorFinderWrapper.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Autofac.Core.Activators.Reflection; + +namespace Orchard.Environment.AutofacUtil.DynamicProxy2 { + class ConstructorFinderWrapper : IConstructorFinder { + private readonly IConstructorFinder _constructorFinder; + private readonly DynamicProxyContext _dynamicProxyContext; + + public ConstructorFinderWrapper(IConstructorFinder constructorFinder, DynamicProxyContext dynamicProxyContext) { + _constructorFinder = constructorFinder; + _dynamicProxyContext = dynamicProxyContext; + } + + public IEnumerable FindConstructors(Type targetType) { + Type proxyType; + if (_dynamicProxyContext.TryGetProxy(targetType, out proxyType)) { + return _constructorFinder.FindConstructors(proxyType); + } + return _constructorFinder.FindConstructors(targetType); + } + } +} diff --git a/src/Orchard/Environment/AutofacUtil/DynamicProxy2/DynamicProxyContext.cs b/src/Orchard/Environment/AutofacUtil/DynamicProxy2/DynamicProxyContext.cs new file mode 100644 index 000000000..587218330 --- /dev/null +++ b/src/Orchard/Environment/AutofacUtil/DynamicProxy2/DynamicProxyContext.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Autofac; +using Autofac.Builder; +using Autofac.Core; +using Castle.Core.Interceptor; +using Castle.DynamicProxy; + +namespace Orchard.Environment.AutofacUtil.DynamicProxy2 { + public class DynamicProxyContext { + const string ProxyContextKey = "Orchard.Environment.AutofacUtil.DynamicProxy2.DynamicProxyContext.ProxyContextKey"; + const string InterceptorServicesKey = "Orchard.Environment.AutofacUtil.DynamicProxy2.DynamicProxyContext.InterceptorServicesKey"; + + readonly IProxyBuilder _proxyBuilder = new DefaultProxyBuilder(); + readonly IDictionary _cache = new Dictionary(); + + /// + /// Static method to resolve the context for a component registration. The context is set + /// by using the registration builder extension method EnableDynamicProxy(context). + /// + public static DynamicProxyContext From(IComponentRegistration registration) { + object value; + if (registration.Metadata.TryGetValue(ProxyContextKey, out value)) + return value as DynamicProxyContext; + return null; + } + + /// + /// Called indirectly from the EnableDynamicProxy extension method. + /// Modifies a registration to support dynamic interception if needed, and act as a normal type otherwise. + /// + public void EnableDynamicProxy( + IRegistrationBuilder registrationBuilder) + where TConcreteReflectionActivatorData : ConcreteReflectionActivatorData { + + // associate this context. used later by static DynamicProxyContext.From() method. + registrationBuilder.WithMetadata(ProxyContextKey, this); + + // put a shim in place. this will return constructors for the proxy class if it interceptors have been added. + registrationBuilder.ActivatorData.ConstructorFinder = new ConstructorFinderWrapper( + registrationBuilder.ActivatorData.ConstructorFinder, this); + + // when component is being resolved, this even handler will place the array of appropriate interceptors as the first argument + registrationBuilder.OnPreparing(e => { + object value; + if (e.Component.Metadata.TryGetValue(InterceptorServicesKey, out value)) { + var interceptorServices = (IEnumerable)value; + var interceptors = interceptorServices.Select(service => e.Context.Resolve(service)).Cast().ToArray(); + var parameter = new PositionalParameter(0, interceptors); + e.Parameters = new[] { parameter }.Concat(e.Parameters).ToArray(); + } + }); + } + + /// + /// Called indirectly from the InterceptedBy extension method. + /// Adds services to the componenent's list of interceptors, activating the need for dynamic proxy + /// + public void AddInterceptorService(IComponentRegistration registration, Service service) { + AddProxy(registration.Activator.LimitType); + + var interceptorServices = Enumerable.Empty(); + object value; + if (registration.Metadata.TryGetValue(InterceptorServicesKey, out value)) { + interceptorServices = (IEnumerable)value; + } + + registration.Metadata[InterceptorServicesKey] = interceptorServices.Concat(new[] { service }).Distinct().ToArray(); + } + + + /// + /// Ensures that a proxy has been generated for the particular type in this context + /// + public void AddProxy(Type type) { + Type proxyType; + if (_cache.TryGetValue(type, out proxyType)) + return; + + lock (_cache) { + if (_cache.TryGetValue(type, out proxyType)) + return; + + _cache[type] = _proxyBuilder.CreateClassProxy(type, ProxyGenerationOptions.Default); + } + } + + /// + /// Determines if a proxy has been generated for the given type, and returns it. + /// + public bool TryGetProxy(Type type, out Type proxyType) { + return _cache.TryGetValue(type, out proxyType); + } + + } +} diff --git a/src/Orchard/Environment/AutofacUtil/DynamicProxy2/DynamicProxyExtensions.cs b/src/Orchard/Environment/AutofacUtil/DynamicProxy2/DynamicProxyExtensions.cs new file mode 100644 index 000000000..0d5c70d13 --- /dev/null +++ b/src/Orchard/Environment/AutofacUtil/DynamicProxy2/DynamicProxyExtensions.cs @@ -0,0 +1,35 @@ +using System; +using Autofac.Builder; +using Autofac.Core; +using Autofac.Features.Scanning; + +namespace Orchard.Environment.AutofacUtil.DynamicProxy2 { + public static class DynamicProxyExtensions { + + public static IRegistrationBuilder EnableDynamicProxy( + this IRegistrationBuilder rb, + DynamicProxyContext dynamicProxyContext) + where TConcreteReflectionActivatorData : ConcreteReflectionActivatorData { + + dynamicProxyContext.EnableDynamicProxy(rb); + + return rb; + } + + public static IRegistrationBuilder EnableDynamicProxy( + this IRegistrationBuilder rb, + DynamicProxyContext dynamicProxyContext) { + + rb.ActivatorData.ConfigurationActions.Add((t, rb2) => rb2.EnableDynamicProxy(dynamicProxyContext)); + return rb; + } + + public static void InterceptedBy(this IComponentRegistration cr) { + var dynamicProxyContext = DynamicProxyContext.From(cr); + if (dynamicProxyContext == null) + throw new ApplicationException(string.Format("Component {0} was not registered with EnableDynamicProxy", cr.Activator.LimitType)); + + dynamicProxyContext.AddInterceptorService(cr, new TypedService(typeof(TService))); + } + } +} diff --git a/src/Orchard/Environment/ExtensibleInterceptionModule.cs b/src/Orchard/Environment/ExtensibleInterceptionModule.cs deleted file mode 100644 index aa6063df8..000000000 --- a/src/Orchard/Environment/ExtensibleInterceptionModule.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Autofac; -using Autofac.Core; -using AutofacContrib.DynamicProxy2; - -namespace Orchard.Environment { - //public class ExtensibleInterceptionModule : InterceptionModule { - // public ExtensibleInterceptionModule(IEnumerable providers) - // : base(new CombinedProvider(providers.Concat(new[] { new FlexibleInterceptorProvider() })), new FlexibleInterceptorAttacher()) { - // } - - // class CombinedProvider : IComponentInterceptorProvider { - // private readonly IEnumerable _providers; - - // public CombinedProvider(IEnumerable providers) { - // _providers = providers; - // } - - // public IEnumerable GetInterceptorServices(IComponentDescriptor descriptor) { - // return _providers - // .SelectMany(x => x.GetInterceptorServices(descriptor)) - // .Distinct() - // .ToList(); - // } - // } - //} -} \ No newline at end of file diff --git a/src/Orchard/Environment/FiniteContainerProvider.cs b/src/Orchard/Environment/FiniteContainerProvider.cs index d012b3d40..2c32f7b49 100644 --- a/src/Orchard/Environment/FiniteContainerProvider.cs +++ b/src/Orchard/Environment/FiniteContainerProvider.cs @@ -1,6 +1,6 @@ using Autofac; using Autofac.Integration.Web; -using Orchard.Environment.ShellBuilders; +using Orchard.Environment.AutofacUtil; namespace Orchard.Environment { diff --git a/src/Orchard/Environment/OrchardStarter.cs b/src/Orchard/Environment/OrchardStarter.cs index 75456b7e9..d4633a565 100644 --- a/src/Orchard/Environment/OrchardStarter.cs +++ b/src/Orchard/Environment/OrchardStarter.cs @@ -3,6 +3,7 @@ using Autofac; using Autofac.Builder; using Autofac.Core; using Autofac.Integration.Web; +using Orchard.Environment.AutofacUtil; using Orchard.Environment.Configuration; using Orchard.Environment.ShellBuilders; using Orchard.Extensions; diff --git a/src/Orchard/Environment/ShellBuilders/DefaultShellContainerFactory.cs b/src/Orchard/Environment/ShellBuilders/DefaultShellContainerFactory.cs index 61451505c..2af7bd087 100644 --- a/src/Orchard/Environment/ShellBuilders/DefaultShellContainerFactory.cs +++ b/src/Orchard/Environment/ShellBuilders/DefaultShellContainerFactory.cs @@ -1,6 +1,8 @@ using System.Collections.Generic; using Autofac; using Autofac.Core; +using Orchard.Environment.AutofacUtil; +using Orchard.Environment.AutofacUtil.DynamicProxy2; using Orchard.Environment.Configuration; namespace Orchard.Environment.ShellBuilders { @@ -19,9 +21,12 @@ namespace Orchard.Environment.ShellBuilders { return null; } + var dynamicProxyContext = new DynamicProxyContext(); + // add module types to container being built var addingModulesAndServices = new ContainerUpdater(); addingModulesAndServices.RegisterInstance(settings).As(); + addingModulesAndServices.RegisterInstance(dynamicProxyContext); addingModulesAndServices.RegisterType().As().SingleInstance(); foreach (var moduleType in _compositionStrategy.GetModuleTypes()) { @@ -32,7 +37,7 @@ namespace Orchard.Environment.ShellBuilders { foreach (var serviceType in _compositionStrategy.GetDependencyTypes()) { foreach (var interfaceType in serviceType.GetInterfaces()) { if (typeof(IDependency).IsAssignableFrom(interfaceType)) { - var registrar = addingModulesAndServices.RegisterType(serviceType).As(interfaceType); + var registrar = addingModulesAndServices.RegisterType(serviceType).As(interfaceType).EnableDynamicProxy(dynamicProxyContext); if (typeof(ISingletonDependency).IsAssignableFrom(interfaceType)) { registrar.SingleInstance(); } diff --git a/src/Orchard/Environment/ShellBuilders/SafeModeShellContainerFactory.cs b/src/Orchard/Environment/ShellBuilders/SafeModeShellContainerFactory.cs index c4cde56f0..7eef7c180 100644 --- a/src/Orchard/Environment/ShellBuilders/SafeModeShellContainerFactory.cs +++ b/src/Orchard/Environment/ShellBuilders/SafeModeShellContainerFactory.cs @@ -10,6 +10,8 @@ using Autofac.Core; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; using Orchard.Data.Builders; +using Orchard.Environment.AutofacUtil; +using Orchard.Environment.AutofacUtil.DynamicProxy2; using Orchard.Environment.Configuration; using Orchard.Extensions; using Orchard.Localization; @@ -39,9 +41,12 @@ namespace Orchard.Environment.ShellBuilders { return null; } + var dynamicProxyContext = new DynamicProxyContext(); + var shellScope = _container.BeginLifetimeScope(); var builder = new ContainerUpdater(); // standard services needed in safe mode + builder.RegisterInstance(dynamicProxyContext); builder.RegisterType().As().InstancePerLifetimeScope(); builder.RegisterType().As().InstancePerLifetimeScope(); builder.RegisterType().As().InstancePerLifetimeScope(); @@ -67,7 +72,7 @@ namespace Orchard.Environment.ShellBuilders { foreach (var serviceType in dependencies) { foreach (var interfaceType in serviceType.GetInterfaces()) { if (typeof(IDependency).IsAssignableFrom(interfaceType)) { - var registrar = builder.RegisterType(serviceType).As(interfaceType); + var registrar = builder.RegisterType(serviceType).As(interfaceType).EnableDynamicProxy(dynamicProxyContext); if (typeof(ISingletonDependency).IsAssignableFrom(interfaceType)) { registrar.SingleInstance(); } diff --git a/src/Orchard/Mvc/MvcModule.cs b/src/Orchard/Mvc/MvcModule.cs index 5e7a23698..6cea5fa3f 100644 --- a/src/Orchard/Mvc/MvcModule.cs +++ b/src/Orchard/Mvc/MvcModule.cs @@ -6,6 +6,7 @@ using System.Web.Routing; using Autofac; using Autofac.Integration.Web; using Autofac.Integration.Web.Mvc; +using Orchard.Environment.AutofacUtil.DynamicProxy2; using Orchard.Mvc.Filters; using Orchard.Extensions; using Autofac.Core; @@ -13,9 +14,11 @@ using Autofac.Core; namespace Orchard.Mvc { public class MvcModule : Module { private readonly IExtensionManager _extensionManager; + private readonly DynamicProxyContext _dynamicProxyContext; - public MvcModule(IExtensionManager extensionManager) { + public MvcModule(IExtensionManager extensionManager, DynamicProxyContext dynamicProxyContext) { _extensionManager = extensionManager; + _dynamicProxyContext = dynamicProxyContext; } protected override void Load(ContainerBuilder moduleBuilder) { @@ -25,6 +28,7 @@ namespace Orchard.Mvc { moduleBuilder.RegisterType().As(actionInvokerService).InstancePerDependency(); moduleBuilder.RegisterControllers(new OrchardControllerIdentificationStrategy(extensions), assemblies.ToArray()) + .EnableDynamicProxy(_dynamicProxyContext) .InjectActionInvoker(actionInvokerService).InstancePerDependency(); moduleBuilder.Register(ctx => HttpContextBaseFactory(ctx)).As().InstancePerDependency(); diff --git a/src/Orchard/Orchard.csproj b/src/Orchard/Orchard.csproj index e57bdb2b0..105c385cf 100644 --- a/src/Orchard/Orchard.csproj +++ b/src/Orchard/Orchard.csproj @@ -43,14 +43,14 @@ False ..\..\lib\autofac\Autofac.Integration.Web.Mvc.dll - - False - ..\..\lib\autofac-contrib\AutofacContrib.DynamicProxy2.dll - False ..\..\lib\Castle Windsor 2.0\bin\Castle.Core.dll + + False + ..\..\lib\Castle Windsor 2.0\bin\Castle.DynamicProxy2.dll + False ..\..\lib\fluentnhibernate\FluentNHibernate.dll @@ -150,10 +150,12 @@ + + + - - + diff --git a/src/Orchard/Security/SecurityModule.cs b/src/Orchard/Security/SecurityModule.cs index df3206f8f..33c3b57c1 100644 --- a/src/Orchard/Security/SecurityModule.cs +++ b/src/Orchard/Security/SecurityModule.cs @@ -1,43 +1,30 @@ using System; -using System.Collections.Generic; -using System.Linq; using System.Reflection; -using Autofac; using Autofac.Core; -using AutofacContrib.DynamicProxy2; using Castle.Core.Interceptor; +using Orchard.Environment.AutofacUtil.DynamicProxy2; using Module = Autofac.Module; namespace Orchard.Security { - //public class SecurityModule : Module { - // protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration) { - // var implementationType = registration.Activator.LimitType; - // var property = FindProperty(implementationType); + public class SecurityModule : Module { + protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration) { + var implementationType = registration.Activator.LimitType; + var property = FindProperty(implementationType); - // if (property != null) { - - // } - // } + if (property != null) { + registration.InterceptedBy(); + } + } - // public IEnumerable GetInterceptorServices(IComponentDescriptor descriptor) { - // var property = FindProperty(descriptor.BestKnownImplementationType); - // if (property != null) { - // if (property.GetGetMethod(true).IsVirtual == false) { - // throw new ApplicationException(string.Format("CurrentUser property must be virtual on class {0}", descriptor.BestKnownImplementationType.FullName)); - // } - // yield return new TypedService(typeof(ISecurityModuleInterceptor)); - // } - // } - - // private static PropertyInfo FindProperty(Type type) { - // return type.GetProperty("CurrentUser", - // BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, - // null, - // typeof(IUser), - // new Type[0], - // null); - // } - //} + private static PropertyInfo FindProperty(Type type) { + return type.GetProperty("CurrentUser", + BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, + null, + typeof(IUser), + new Type[0], + null); + } + } public interface ISecurityModuleInterceptor : IInterceptor, IDependency { diff --git a/src/Orchard/Settings/SettingsModule.cs b/src/Orchard/Settings/SettingsModule.cs index b47474104..d77d3b820 100644 --- a/src/Orchard/Settings/SettingsModule.cs +++ b/src/Orchard/Settings/SettingsModule.cs @@ -1,34 +1,30 @@ using System; -using System.Collections.Generic; using System.Reflection; -using Autofac; using Autofac.Core; -using AutofacContrib.DynamicProxy2; using Castle.Core.Interceptor; -using Orchard.Security; +using Orchard.Environment.AutofacUtil.DynamicProxy2; using Module = Autofac.Module; namespace Orchard.Settings { - //public class SettingsModule : Module, IComponentInterceptorProvider { - // public IEnumerable GetInterceptorServices(IComponentDescriptor descriptor) { - // var property = FindProperty(descriptor.BestKnownImplementationType); - // if (property != null) { - // if (property.GetGetMethod(true).IsVirtual == false) { - // throw new ApplicationException(string.Format("CurrentSite property must be virtual on class {0}", descriptor.BestKnownImplementationType.FullName)); - // } - // yield return new TypedService(typeof(ISettingsModuleInterceptor)); - // } - // } + public class SettingsModule : Module { + protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration) { + var implementationType = registration.Activator.LimitType; + var property = FindProperty(implementationType); - // private static PropertyInfo FindProperty(Type type) { - // return type.GetProperty("CurrentSite", - // BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, - // null, - // typeof(ISite), - // new Type[0], - // null); - // } - //} + if (property != null) { + registration.InterceptedBy(); + } + } + + private static PropertyInfo FindProperty(Type type) { + return type.GetProperty("CurrentSite", + BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, + null, + typeof(ISite), + new Type[0], + null); + } + } public interface ISettingsModuleInterceptor : IInterceptor, IDependency {