Browse Source

#15 Implemented interception via Autofac.

pull/81/head
Halil İbrahim Kalkan 10 years ago
parent
commit
7998045a14
  1. 4
      src/AbpDesk/AbpDesk.ConsoleDemo/AbpDesk/ConsoleDemo/AbpDeskConsoleDemoModule.cs
  2. 2
      src/AbpDesk/AbpDesk.ConsoleDemo/AbpDesk/ConsoleDemo/Program.cs
  3. 4
      src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs
  4. 43
      src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs
  5. 148
      src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs
  6. 87
      src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProvider.cs
  7. 77
      src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProviderFactory.cs
  8. 67
      src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScope.cs
  9. 65
      src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScopeFactory.cs
  10. 47
      src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/ServiceCollectionExtensions.cs
  11. 1
      src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj
  12. 11
      src/Volo.Abp.Autofac/Volo/Abp/Autofac/AbpAutofacModule.cs
  13. 90
      src/Volo.Abp.Autofac/Volo/Abp/Autofac/AbpAutofacServiceProviderFactory.cs
  14. 14
      src/Volo.Abp.Castle.Core/Volo/Abp/Castle/AbpCastleCoreModule.cs
  15. 16
      src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs

4
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)

2
src/AbpDesk/AbpDesk.ConsoleDemo/AbpDesk/ConsoleDemo/Program.cs

@ -48,7 +48,7 @@ namespace AbpDesk.ConsoleDemo
{
application
.ServiceProvider
.GetRequiredService<TicketLister2>()
.GetRequiredService<TicketLister>()
.List();
application

4
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
{

43
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<TLimit, TConcreteReflectionActivatorData, TRegistrationStyle> ApplyAbpConcepts<TLimit, TConcreteReflectionActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, TConcreteReflectionActivatorData, TRegistrationStyle> registrationBuilder)
where TConcreteReflectionActivatorData : ConcreteReflectionActivatorData
{
//TODO: Refactor to an extensible way!
var serviceType = registrationBuilder.RegistrationData.Services.OfType<IServiceWithType>().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;
}
}
}

148
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
{
/// <summary>
/// Extension methods for registering ASP.NET Core dependencies with Autofac.
/// </summary>
public static class AutofacRegistration
{
/// <summary>
/// Populates the Autofac container builder with the set of registered service descriptors
/// and makes <see cref="IServiceProvider"/> and <see cref="IServiceScopeFactory"/>
/// available in the container.
/// </summary>
/// <param name="builder">
/// The <see cref="ContainerBuilder"/> into which the registrations should be made.
/// </param>
/// <param name="descriptors">
/// The set of service descriptors to register in the container.
/// </param>
public static void Populate(
this ContainerBuilder builder,
IEnumerable<ServiceDescriptor> descriptors)
{
builder.RegisterType<AutofacServiceProvider>().As<IServiceProvider>();
builder.RegisterType<AutofacServiceScopeFactory>().As<IServiceScopeFactory>();
Register(builder, descriptors);
}
/// <summary>
/// Configures the lifecycle on a service registration.
/// </summary>
/// <typeparam name="TActivatorData">The activator data type.</typeparam>
/// <typeparam name="TRegistrationStyle">The object registration style.</typeparam>
/// <param name="registrationBuilder">The registration being built.</param>
/// <param name="lifecycleKind">The lifecycle specified on the service registration.</param>
/// <returns>
/// The <paramref name="registrationBuilder" />, configured with the proper lifetime scope,
/// and available for additional configuration.
/// </returns>
private static IRegistrationBuilder<object, TActivatorData, TRegistrationStyle> ConfigureLifecycle<TActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<object, TActivatorData, TRegistrationStyle> 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;
}
/// <summary>
/// Populates the Autofac container builder with the set of registered service descriptors.
/// </summary>
/// <param name="builder">
/// The <see cref="ContainerBuilder"/> into which the registrations should be made.
/// </param>
/// <param name="descriptors">
/// The set of service descriptors to register in the container.
/// </param>
private static void Register(
ContainerBuilder builder,
IEnumerable<ServiceDescriptor> 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<IServiceProvider>();
return descriptor.ImplementationFactory(serviceProvider);
})
.ConfigureLifecycle(descriptor.Lifetime)
.CreateRegistration();
builder.RegisterComponent(registration);
}
else
{
builder
.RegisterInstance(descriptor.ImplementationInstance)
.As(descriptor.ServiceType)
.ConfigureLifecycle(descriptor.Lifetime);
}
}
}
}
}

87
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
{
/// <summary>
/// Autofac implementation of the ASP.NET Core <see cref="IServiceProvider"/>.
/// </summary>
/// <seealso cref="System.IServiceProvider" />
/// <seealso cref="Microsoft.Extensions.DependencyInjection.ISupportRequiredService" />
public class AutofacServiceProvider : IServiceProvider, ISupportRequiredService
{
private readonly IComponentContext _componentContext;
/// <summary>
/// Initializes a new instance of the <see cref="AutofacServiceProvider"/> class.
/// </summary>
/// <param name="componentContext">
/// The component context from which services should be resolved.
/// </param>
public AutofacServiceProvider(IComponentContext componentContext)
{
this._componentContext = componentContext;
}
/// <summary>
/// Gets service of type <paramref name="serviceType" /> from the
/// <see cref="AutofacServiceProvider" /> and requires it be present.
/// </summary>
/// <param name="serviceType">
/// An object that specifies the type of service object to get.
/// </param>
/// <returns>
/// A service object of type <paramref name="serviceType" />.
/// </returns>
/// <exception cref="Autofac.Core.Registration.ComponentNotRegisteredException">
/// Thrown if the <paramref name="serviceType" /> isn't registered with the container.
/// </exception>
/// <exception cref="Autofac.Core.DependencyResolutionException">
/// Thrown if the object can't be resolved from the container.
/// </exception>
public object GetRequiredService(Type serviceType)
{
return this._componentContext.Resolve(serviceType);
}
/// <summary>
/// Gets the service object of the specified type.
/// </summary>
/// <param name="serviceType">
/// An object that specifies the type of service object to get.
/// </param>
/// <returns>
/// A service object of type <paramref name="serviceType" />; or <see langword="null" />
/// if there is no service object of type <paramref name="serviceType" />.
/// </returns>
public object GetService(Type serviceType)
{
return this._componentContext.ResolveOptional(serviceType);
}
}
}

77
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
{
/// <summary>
/// A factory for creating a <see cref="ContainerBuilder"/> and an <see cref="T:System.IServiceProvider" />.
/// </summary>
public class AutofacServiceProviderFactory : IServiceProviderFactory<ContainerBuilder>
{
private readonly Action<ContainerBuilder> _configurationAction;
/// <summary>
/// Initializes a new instance of the <see cref="AutofacServiceProviderFactory"/> class.
/// </summary>
/// <param name="configurationAction">Action on a <see cref="ContainerBuilder"/> that adds component registrations to the conatiner.</param>
public AutofacServiceProviderFactory(Action<ContainerBuilder> configurationAction = null)
{
_configurationAction = configurationAction ?? (builder => { });
}
/// <summary>
/// Creates a container builder from an <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
/// </summary>
/// <param name="services">The collection of services</param>
/// <returns>A container builder that can be used to create an <see cref="T:System.IServiceProvider" />.</returns>
public ContainerBuilder CreateBuilder(IServiceCollection services)
{
var builder = new ContainerBuilder();
builder.Populate(services);
_configurationAction(builder);
return builder;
}
/// <summary>
/// Creates an <see cref="T:System.IServiceProvider" /> from the container builder.
/// </summary>
/// <param name="containerBuilder">The container builder</param>
/// <returns>An <see cref="T:System.IServiceProvider" /></returns>
public IServiceProvider CreateServiceProvider(ContainerBuilder containerBuilder)
{
if (containerBuilder == null) throw new ArgumentNullException(nameof(containerBuilder));
var container = containerBuilder.Build();
return new AutofacServiceProvider(container);
}
}
}

67
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
{
/// <summary>
/// Autofac implementation of the ASP.NET Core <see cref="IServiceScope"/>.
/// </summary>
/// <seealso cref="Microsoft.Extensions.DependencyInjection.IServiceScope" />
internal class AutofacServiceScope : IServiceScope
{
private readonly ILifetimeScope _lifetimeScope;
/// <summary>
/// Initializes a new instance of the <see cref="AutofacServiceScope"/> class.
/// </summary>
/// <param name="lifetimeScope">
/// The lifetime scope from which services should be resolved for this service scope.
/// </param>
public AutofacServiceScope(ILifetimeScope lifetimeScope)
{
this._lifetimeScope = lifetimeScope;
this.ServiceProvider = this._lifetimeScope.Resolve<IServiceProvider>();
}
/// <summary>
/// Gets an <see cref="IServiceProvider" /> corresponding to this service scope.
/// </summary>
/// <value>
/// An <see cref="IServiceProvider" /> that can be used to resolve dependencies from the scope.
/// </value>
public IServiceProvider ServiceProvider { get; }
/// <summary>
/// Disposes of the lifetime scope and resolved disposable services.
/// </summary>
public void Dispose()
{
this._lifetimeScope.Dispose();
}
}
}

65
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
{
/// <summary>
/// Autofac implementation of the ASP.NET Core <see cref="IServiceScopeFactory"/>.
/// </summary>
/// <seealso cref="Microsoft.Extensions.DependencyInjection.IServiceScopeFactory" />
[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;
/// <summary>
/// Initializes a new instance of the <see cref="AutofacServiceScopeFactory"/> class.
/// </summary>
/// <param name="lifetimeScope">The lifetime scope.</param>
public AutofacServiceScopeFactory(ILifetimeScope lifetimeScope)
{
this._lifetimeScope = lifetimeScope;
}
/// <summary>
/// Creates an <see cref="IServiceScope" /> which contains an
/// <see cref="System.IServiceProvider" /> used to resolve dependencies within
/// the scope.
/// </summary>
/// <returns>
/// An <see cref="IServiceScope" /> controlling the lifetime of the scope. Once
/// this is disposed, any scoped services that have been resolved
/// from the <see cref="IServiceScope.ServiceProvider" />
/// will also be disposed.
/// </returns>
public IServiceScope CreateScope()
{
return new AutofacServiceScope(this._lifetimeScope.BeginLifetimeScope());
}
}
}

47
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
{
/// <summary>
/// Extension methods on <see cref="IServiceCollection"/> to register the <see cref="IServiceProviderFactory{TContainerBuilder}"/>.
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// Adds the <see cref="AutofacServiceProviderFactory"/> to the service collection.
/// </summary>
/// <param name="services">The service collection to add the factory to.</param>
/// <param name="configurationAction">Action on a <see cref="ContainerBuilder"/> that adds component registrations to the conatiner.</param>
/// <returns>The service collection.</returns>
public static IServiceCollection AddAutofac(this IServiceCollection services, Action<ContainerBuilder> configurationAction = null)
{
return services.AddSingleton<IServiceProviderFactory<ContainerBuilder>>(new AutofacServiceProviderFactory(configurationAction));
}
}
}

1
src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj

@ -13,7 +13,6 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.1.0" />
<PackageReference Include="Autofac.Extras.DynamicProxy" Version="4.2.1" />
</ItemGroup>

11
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
{
}
}

90
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<IServiceWithType>().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<object> args, OnServiceRegistredArgs registredArgs)
{
var mainService = args.Component.Services.OfType<IServiceWithType>().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
// )
//);
}
}
}
}

14
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<>));
}
}
}

16
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<TInterceptor> : IInterceptor
where TInterceptor : IAbpInterceptor
{
private readonly TInterceptor _abpInterceptor;
public CastleAbpInterceptorAdapter(TInterceptor abpInterceptor)
{
_abpInterceptor = abpInterceptor;
}
public void Intercept(IInvocation invocation)
{
_abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation));
}
}
}

Loading…
Cancel
Save