From 7998045a1445465b2661276f71049934b2070d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 3 May 2017 14:33:35 +0300 Subject: [PATCH] #15 Implemented interception via Autofac. --- .../ConsoleDemo/AbpDeskConsoleDemoModule.cs | 4 +- .../AbpDesk/ConsoleDemo/Program.cs | 2 +- .../AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs | 4 +- .../AbpRegistrationBuilderExtensions.cs | 43 +++++ .../AutofacRegistration.cs | 148 ++++++++++++++++++ .../AutofacServiceProvider.cs | 87 ++++++++++ .../AutofacServiceProviderFactory.cs | 77 +++++++++ .../AutofacServiceScope.cs | 67 ++++++++ .../AutofacServiceScopeFactory.cs | 65 ++++++++ .../ServiceCollectionExtensions.cs | 47 ++++++ src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj | 1 - .../Volo/Abp/Autofac/AbpAutofacModule.cs | 11 ++ .../AbpAutofacServiceProviderFactory.cs | 90 ----------- .../Volo/Abp/Castle/AbpCastleCoreModule.cs | 14 ++ .../CastleAbpInterceptorAdapter.cs | 16 ++ 15 files changed, 582 insertions(+), 94 deletions(-) create mode 100644 src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs create mode 100644 src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs create mode 100644 src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProvider.cs create mode 100644 src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProviderFactory.cs create mode 100644 src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScope.cs create mode 100644 src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScopeFactory.cs create mode 100644 src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/ServiceCollectionExtensions.cs create mode 100644 src/Volo.Abp.Autofac/Volo/Abp/Autofac/AbpAutofacModule.cs create mode 100644 src/Volo.Abp.Castle.Core/Volo/Abp/Castle/AbpCastleCoreModule.cs diff --git a/src/AbpDesk/AbpDesk.ConsoleDemo/AbpDesk/ConsoleDemo/AbpDeskConsoleDemoModule.cs b/src/AbpDesk/AbpDesk.ConsoleDemo/AbpDesk/ConsoleDemo/AbpDeskConsoleDemoModule.cs index cc38468796..d8f17cf721 100644 --- a/src/AbpDesk/AbpDesk.ConsoleDemo/AbpDesk/ConsoleDemo/AbpDeskConsoleDemoModule.cs +++ b/src/AbpDesk/AbpDesk.ConsoleDemo/AbpDesk/ConsoleDemo/AbpDeskConsoleDemoModule.cs @@ -3,6 +3,7 @@ using AbpDesk.Blogging; using AbpDesk.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Autofac; using Volo.Abp.Identity.EntityFrameworkCore; using Volo.Abp.Modularity; @@ -12,7 +13,8 @@ namespace AbpDesk.ConsoleDemo typeof(AbpDeskApplicationModule), typeof(AbpDeskEntityFrameworkCoreModule), typeof(AbpIdentityEntityFrameworkCoreModule), - typeof(AbpDeskMongoBlogModule))] + typeof(AbpDeskMongoBlogModule), + typeof(AbpAutofacModule))] public class AbpDeskConsoleDemoModule : AbpModule { public override void ConfigureServices(IServiceCollection services) diff --git a/src/AbpDesk/AbpDesk.ConsoleDemo/AbpDesk/ConsoleDemo/Program.cs b/src/AbpDesk/AbpDesk.ConsoleDemo/AbpDesk/ConsoleDemo/Program.cs index fd661d9277..13d3465558 100644 --- a/src/AbpDesk/AbpDesk.ConsoleDemo/AbpDesk/ConsoleDemo/Program.cs +++ b/src/AbpDesk/AbpDesk.ConsoleDemo/AbpDesk/ConsoleDemo/Program.cs @@ -48,7 +48,7 @@ namespace AbpDesk.ConsoleDemo { application .ServiceProvider - .GetRequiredService() + .GetRequiredService() .List(); application diff --git a/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs b/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs index b0cff4f325..d4643e11e8 100644 --- a/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs +++ b/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs @@ -10,6 +10,7 @@ using Volo.Abp; using Volo.Abp.AspNetCore.EmbeddedFiles; using Volo.Abp.AspNetCore.Modularity; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; +using Volo.Abp.Autofac; using Volo.Abp.Identity; using Volo.Abp.Identity.Web; using Volo.Abp.Modularity; @@ -23,7 +24,8 @@ namespace AbpDesk.Web.Mvc typeof(AbpDeskApplicationModule), typeof(AbpDeskEntityFrameworkCoreModule), typeof(AbpIdentityHttpApiClientModule), - typeof(AbpIdentityWebModule) + typeof(AbpIdentityWebModule), + typeof(AbpAutofacModule) )] public class AbpDeskWebMvcModule : AbpModule { diff --git a/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs b/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs new file mode 100644 index 0000000000..80bc8fe279 --- /dev/null +++ b/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs @@ -0,0 +1,43 @@ +using System.Linq; +using System.Reflection; +using Autofac.Core; +using Autofac.Extras.DynamicProxy; +using Volo.Abp.Application.Services; +using Volo.Abp.Castle.DynamicProxy; +using Volo.Abp.Uow; + +namespace Autofac.Builder +{ + public static class AbpRegistrationBuilderExtensions + { + public static IRegistrationBuilder ApplyAbpConcepts( + this IRegistrationBuilder registrationBuilder) + where TConcreteReflectionActivatorData : ConcreteReflectionActivatorData + { + //TODO: Refactor to an extensible way! + + var serviceType = registrationBuilder.RegistrationData.Services.OfType().FirstOrDefault()?.ServiceType; + + if (serviceType != null) + { + if (typeof(IApplicationService).IsAssignableFrom(serviceType)) + { + if (serviceType.GetTypeInfo().IsInterface) + { + registrationBuilder = registrationBuilder.EnableInterfaceInterceptors(); + } + else + { + registrationBuilder = registrationBuilder.EnableClassInterceptors(); + } + + registrationBuilder.InterceptedBy( + typeof(CastleAbpInterceptorAdapter<>).MakeGenericType(typeof(UnitOfWorkInterceptor)) + ); + } + } + + return registrationBuilder; + } + } +} diff --git a/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs b/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs new file mode 100644 index 0000000000..1d5e688dda --- /dev/null +++ b/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs @@ -0,0 +1,148 @@ +// This software is part of the Autofac IoC container +// Copyright © 2015 Autofac Contributors +// http://autofac.org +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Reflection; +using Autofac.Builder; +using Microsoft.Extensions.DependencyInjection; + +namespace Autofac.Extensions.DependencyInjection +{ + /// + /// Extension methods for registering ASP.NET Core dependencies with Autofac. + /// + public static class AutofacRegistration + { + /// + /// Populates the Autofac container builder with the set of registered service descriptors + /// and makes and + /// available in the container. + /// + /// + /// The into which the registrations should be made. + /// + /// + /// The set of service descriptors to register in the container. + /// + public static void Populate( + this ContainerBuilder builder, + IEnumerable descriptors) + { + builder.RegisterType().As(); + builder.RegisterType().As(); + + Register(builder, descriptors); + } + + /// + /// Configures the lifecycle on a service registration. + /// + /// The activator data type. + /// The object registration style. + /// The registration being built. + /// The lifecycle specified on the service registration. + /// + /// The , configured with the proper lifetime scope, + /// and available for additional configuration. + /// + private static IRegistrationBuilder ConfigureLifecycle( + this IRegistrationBuilder registrationBuilder, + ServiceLifetime lifecycleKind) + { + switch (lifecycleKind) + { + case ServiceLifetime.Singleton: + registrationBuilder.SingleInstance(); + break; + case ServiceLifetime.Scoped: + registrationBuilder.InstancePerLifetimeScope(); + break; + case ServiceLifetime.Transient: + registrationBuilder.InstancePerDependency(); + break; + } + + return registrationBuilder; + } + + /// + /// Populates the Autofac container builder with the set of registered service descriptors. + /// + /// + /// The into which the registrations should be made. + /// + /// + /// The set of service descriptors to register in the container. + /// + private static void Register( + ContainerBuilder builder, + IEnumerable descriptors) + { + foreach (var descriptor in descriptors) + { + if (descriptor.ImplementationType != null) + { + // Test if the an open generic type is being registered + var serviceTypeInfo = descriptor.ServiceType.GetTypeInfo(); + if (serviceTypeInfo.IsGenericTypeDefinition) + { + builder + .RegisterGeneric(descriptor.ImplementationType) + .As(descriptor.ServiceType) + .ConfigureLifecycle(descriptor.Lifetime); + } + else + { + builder + .RegisterType(descriptor.ImplementationType) + .As(descriptor.ServiceType) + .ConfigureLifecycle(descriptor.Lifetime) + .ApplyAbpConcepts(); + } + } + else if (descriptor.ImplementationFactory != null) + { + var registration = RegistrationBuilder.ForDelegate(descriptor.ServiceType, (context, parameters) => + { + var serviceProvider = context.Resolve(); + return descriptor.ImplementationFactory(serviceProvider); + }) + .ConfigureLifecycle(descriptor.Lifetime) + .CreateRegistration(); + + builder.RegisterComponent(registration); + } + else + { + builder + .RegisterInstance(descriptor.ImplementationInstance) + .As(descriptor.ServiceType) + .ConfigureLifecycle(descriptor.Lifetime); + } + } + } + } +} diff --git a/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProvider.cs b/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProvider.cs new file mode 100644 index 0000000000..ff2d45b2a4 --- /dev/null +++ b/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProvider.cs @@ -0,0 +1,87 @@ +// This software is part of the Autofac IoC container +// Copyright © 2015 Autofac Contributors +// http://autofac.org +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +using System; +using Microsoft.Extensions.DependencyInjection; + +namespace Autofac.Extensions.DependencyInjection +{ + /// + /// Autofac implementation of the ASP.NET Core . + /// + /// + /// + public class AutofacServiceProvider : IServiceProvider, ISupportRequiredService + { + private readonly IComponentContext _componentContext; + + /// + /// Initializes a new instance of the class. + /// + /// + /// The component context from which services should be resolved. + /// + public AutofacServiceProvider(IComponentContext componentContext) + { + this._componentContext = componentContext; + } + + /// + /// Gets service of type from the + /// and requires it be present. + /// + /// + /// An object that specifies the type of service object to get. + /// + /// + /// A service object of type . + /// + /// + /// Thrown if the isn't registered with the container. + /// + /// + /// Thrown if the object can't be resolved from the container. + /// + public object GetRequiredService(Type serviceType) + { + return this._componentContext.Resolve(serviceType); + } + + /// + /// Gets the service object of the specified type. + /// + /// + /// An object that specifies the type of service object to get. + /// + /// + /// A service object of type ; or + /// if there is no service object of type . + /// + public object GetService(Type serviceType) + { + return this._componentContext.ResolveOptional(serviceType); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProviderFactory.cs b/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProviderFactory.cs new file mode 100644 index 0000000000..8e0d4f574d --- /dev/null +++ b/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProviderFactory.cs @@ -0,0 +1,77 @@ +// This software is part of the Autofac IoC container +// Copyright © 2017 Autofac Contributors +// http://autofac.org +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +using System; +using Microsoft.Extensions.DependencyInjection; + +namespace Autofac.Extensions.DependencyInjection +{ + /// + /// A factory for creating a and an . + /// + public class AutofacServiceProviderFactory : IServiceProviderFactory + { + private readonly Action _configurationAction; + + /// + /// Initializes a new instance of the class. + /// + /// Action on a that adds component registrations to the conatiner. + public AutofacServiceProviderFactory(Action configurationAction = null) + { + _configurationAction = configurationAction ?? (builder => { }); + } + + /// + /// Creates a container builder from an . + /// + /// The collection of services + /// A container builder that can be used to create an . + public ContainerBuilder CreateBuilder(IServiceCollection services) + { + var builder = new ContainerBuilder(); + + builder.Populate(services); + + _configurationAction(builder); + + return builder; + } + + /// + /// Creates an from the container builder. + /// + /// The container builder + /// An + public IServiceProvider CreateServiceProvider(ContainerBuilder containerBuilder) + { + if (containerBuilder == null) throw new ArgumentNullException(nameof(containerBuilder)); + + var container = containerBuilder.Build(); + + return new AutofacServiceProvider(container); + } + } +} diff --git a/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScope.cs b/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScope.cs new file mode 100644 index 0000000000..425c6769da --- /dev/null +++ b/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScope.cs @@ -0,0 +1,67 @@ +// This software is part of the Autofac IoC container +// Copyright © 2015 Autofac Contributors +// http://autofac.org +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +using System; +using Microsoft.Extensions.DependencyInjection; + +namespace Autofac.Extensions.DependencyInjection +{ + /// + /// Autofac implementation of the ASP.NET Core . + /// + /// + internal class AutofacServiceScope : IServiceScope + { + private readonly ILifetimeScope _lifetimeScope; + + /// + /// Initializes a new instance of the class. + /// + /// + /// The lifetime scope from which services should be resolved for this service scope. + /// + public AutofacServiceScope(ILifetimeScope lifetimeScope) + { + this._lifetimeScope = lifetimeScope; + this.ServiceProvider = this._lifetimeScope.Resolve(); + } + + /// + /// Gets an corresponding to this service scope. + /// + /// + /// An that can be used to resolve dependencies from the scope. + /// + public IServiceProvider ServiceProvider { get; } + + /// + /// Disposes of the lifetime scope and resolved disposable services. + /// + public void Dispose() + { + this._lifetimeScope.Dispose(); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScopeFactory.cs b/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScopeFactory.cs new file mode 100644 index 0000000000..31917fd079 --- /dev/null +++ b/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScopeFactory.cs @@ -0,0 +1,65 @@ +// This software is part of the Autofac IoC container +// Copyright © 2015 Autofac Contributors +// http://autofac.org +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +using System.Diagnostics.CodeAnalysis; +using Microsoft.Extensions.DependencyInjection; + +namespace Autofac.Extensions.DependencyInjection +{ + /// + /// Autofac implementation of the ASP.NET Core . + /// + /// + [SuppressMessage("Microsoft.ApiDesignGuidelines", "CA2213", Justification = "The creator of the root service lifetime scope is responsible for disposal.")] + internal class AutofacServiceScopeFactory : IServiceScopeFactory + { + private readonly ILifetimeScope _lifetimeScope; + + /// + /// Initializes a new instance of the class. + /// + /// The lifetime scope. + public AutofacServiceScopeFactory(ILifetimeScope lifetimeScope) + { + this._lifetimeScope = lifetimeScope; + } + + /// + /// Creates an which contains an + /// used to resolve dependencies within + /// the scope. + /// + /// + /// An controlling the lifetime of the scope. Once + /// this is disposed, any scoped services that have been resolved + /// from the + /// will also be disposed. + /// + public IServiceScope CreateScope() + { + return new AutofacServiceScope(this._lifetimeScope.BeginLifetimeScope()); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/ServiceCollectionExtensions.cs b/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/ServiceCollectionExtensions.cs new file mode 100644 index 0000000000..5552cda7b2 --- /dev/null +++ b/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/ServiceCollectionExtensions.cs @@ -0,0 +1,47 @@ +// This software is part of the Autofac IoC container +// Copyright © 2017 Autofac Contributors +// http://autofac.org +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +using System; +using Microsoft.Extensions.DependencyInjection; + +namespace Autofac.Extensions.DependencyInjection +{ + /// + /// Extension methods on to register the . + /// + public static class ServiceCollectionExtensions + { + /// + /// Adds the to the service collection. + /// + /// The service collection to add the factory to. + /// Action on a that adds component registrations to the conatiner. + /// The service collection. + public static IServiceCollection AddAutofac(this IServiceCollection services, Action configurationAction = null) + { + return services.AddSingleton>(new AutofacServiceProviderFactory(configurationAction)); + } + } +} diff --git a/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj b/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj index 233560f871..030a65896e 100644 --- a/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj +++ b/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj @@ -13,7 +13,6 @@ - diff --git a/src/Volo.Abp.Autofac/Volo/Abp/Autofac/AbpAutofacModule.cs b/src/Volo.Abp.Autofac/Volo/Abp/Autofac/AbpAutofacModule.cs new file mode 100644 index 0000000000..0b8ae6a39e --- /dev/null +++ b/src/Volo.Abp.Autofac/Volo/Abp/Autofac/AbpAutofacModule.cs @@ -0,0 +1,11 @@ +using Volo.Abp.Castle; +using Volo.Abp.Modularity; + +namespace Volo.Abp.Autofac +{ + [DependsOn(typeof(AbpCastleCoreModule))] + public class AbpAutofacModule : AbpModule + { + + } +} diff --git a/src/Volo.Abp.Autofac/Volo/Abp/Autofac/AbpAutofacServiceProviderFactory.cs b/src/Volo.Abp.Autofac/Volo/Abp/Autofac/AbpAutofacServiceProviderFactory.cs index 59502fb2ac..e3f027aa7c 100644 --- a/src/Volo.Abp.Autofac/Volo/Abp/Autofac/AbpAutofacServiceProviderFactory.cs +++ b/src/Volo.Abp.Autofac/Volo/Abp/Autofac/AbpAutofacServiceProviderFactory.cs @@ -1,13 +1,7 @@ using System; -using System.Linq; -using System.Reflection; using Autofac; -using Autofac.Core; using Autofac.Extensions.DependencyInjection; -using Castle.DynamicProxy; using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Castle.DynamicProxy; -using Volo.Abp.DynamicProxy; namespace Volo.Abp.Autofac { @@ -42,91 +36,7 @@ namespace Volo.Abp.Autofac { Check.NotNull(containerBuilder, nameof(containerBuilder)); - HandleRegistrationActions(containerBuilder); - return new AutofacServiceProvider(containerBuilder.Build()); } - - private static readonly ProxyGenerator _proxyGenerator = new ProxyGenerator(); - - private void HandleRegistrationActions(ContainerBuilder containerBuilder) - { - var registrationActions = _services.GetServiceRegistrationActionList(); - containerBuilder.RegisterCallback(registry => - { - foreach (var registration in registry.Registrations) - { - var registredArgs = new OnServiceRegistredArgs(registration.Activator.LimitType); - - foreach (var registrationAction in registrationActions) - { - registrationAction(registredArgs); - } - - registration.Preparing += (sender, args) => - { - - }; - - registration.Activating += (sender, args) => - { - if (args.Component.Services.OfType().Any(swt => !swt.ServiceType.GetTypeInfo().IsVisible) || args.Instance.GetType().Namespace.StartsWith("Castle.Proxies")) - { - return; - } - - if (registredArgs.Interceptors.Any()) - { - ApplyInterceptors(args, registredArgs); - } - }; - } - }); - } - - private static void ApplyInterceptors(ActivatingEventArgs args, OnServiceRegistredArgs registredArgs) - { - var mainService = args.Component.Services.OfType().FirstOrDefault()?.ServiceType; - if (mainService == null) - { - return; - } - - var interceptorInstances = registredArgs.Interceptors - .Select(i => (IInterceptor)new CastleAbpInterceptorAdapter((IAbpInterceptor)args.Context.Resolve(i))) - .ToArray(); - - if (mainService.GetTypeInfo().IsInterface) - { - args.ReplaceInstance( - _proxyGenerator - .CreateInterfaceProxyWithTargetInterface( - mainService, - args.Instance, - interceptorInstances - ) - ); - } - else - { - //var proxied = _proxyGenerator - // .CreateClassProxyWithTarget( - // mainService, - // args.Instance, - // interceptorInstances - // ); - - //args.ReplaceInstance(proxied); - - //args.ReplaceInstance( - // _proxyGenerator - // .CreateClassProxyWithTarget( - // mainService, - // args.Instance, - // interceptorInstances - // ) - //); - } - } } } \ No newline at end of file diff --git a/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/AbpCastleCoreModule.cs b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/AbpCastleCoreModule.cs new file mode 100644 index 0000000000..d250aab5d0 --- /dev/null +++ b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/AbpCastleCoreModule.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Castle.DynamicProxy; +using Volo.Abp.Modularity; + +namespace Volo.Abp.Castle +{ + public class AbpCastleCoreModule : AbpModule + { + public override void ConfigureServices(IServiceCollection services) + { + services.AddTransient(typeof(CastleAbpInterceptorAdapter<>)); + } + } +} diff --git a/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs index 8a999d3433..5d27f8e025 100644 --- a/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs +++ b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs @@ -17,4 +17,20 @@ namespace Volo.Abp.Castle.DynamicProxy _abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation)); } } + + public class CastleAbpInterceptorAdapter : IInterceptor + where TInterceptor : IAbpInterceptor + { + private readonly TInterceptor _abpInterceptor; + + public CastleAbpInterceptorAdapter(TInterceptor abpInterceptor) + { + _abpInterceptor = abpInterceptor; + } + + public void Intercept(IInvocation invocation) + { + _abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation)); + } + } }