上一篇咱们讲了Abp的核心模块,这一篇咱们把DI 的serviceProvider替换成Autofac,另外添加动态代理拦截器功能。动态代理指从DI容器获取组件实例时组件实例不是原实例,而是代理实例。代理实例是对原实例进行了封装, 在实例方法先后添加逻辑处理,让获取的对象表现基于应有对象但又有本身的逻辑。举个例子,代理对象方法能够在原方法先后记录时间戳,来分析原方法的处理时长。Abp Core默认使用的是微软官方的DI实现, 那个功能较简单没有代理功能,为了添加动态代理功能,咱们把DI实现替换为Autofac,并使用Autofac集成的代理实现方式Castle Core。
集成Autofac,咱们须要添加Volo.Abp.Autofac包,这个包自己是Abp模块,其依赖AbpCastleCoreModule模块(Volo.Abp.CatleCore)html
namespace Volo.Abp.Autofac { [DependsOn(typeof(AbpCastleCoreModule))] public class AbpAutofacModule : AbpModule { } }
因此咱们添加Volo.Abp.Autofac包并让咱们的应用模块DependsOn(typeof(AbpAutofacModule))就自动的把AbpAutofacModule,AbpCastleCoreModule加入到咱们的Core中进行模块管理,也就是说那些基于约定的服务会自动注册到咱们的abpApplication.Services中,很是的方便。咱们在使用Abp中发现好多第三方库都有对应的Volo.Abp.Xxx包也是这个道理,经过把包加入咱们Abp的模块管理体系,把各自的服务注册放入各自的包当中,这样咱们的应用代码就不须要一个一个的注册这些三方库服务,应用模块直接添加DependsOn(typeof(Xxx))便可。api
Abp集成Autofac很是简单 var application = services.AddApplication<TStartupModule>(option=>options.UseAutofac(););
咱们看下UseAutofac这个方法app
public static void UseAutofac(this AbpApplicationCreationOptions options) { var builder = new ContainerBuilder(); options.Services.AddObjectAccessor(builder); options.Services.AddSingleton((IServiceProviderFactory<ContainerBuilder>) new AbpAutofacServiceProviderFactory(builder)); }
回忆上一篇最后的代码,因为注册了IServiceProviderFactory<ContainerBuilder>,因而使用该实例serviceProviderFactory的工厂方法serviceProviderFactory.CreateServiceProvider(serviceProviderFactory.CreateBuilder(services)完成DI容器IServiceProvider的建立,这就把DI容器具体的建立逻辑交给了AbpAutofacServiceProviderFactory,很是巧妙的设计。ide
public ContainerBuilder CreateBuilder(IServiceCollection services) { _services = services; _builder.Populate(services); return _builder; }
在AbpAutofacServiceProviderFactory中CreateBuilder调用了方法_builder.Populate(services);注意这里的Populate方法是
Autofac.Extensions.DependencyInjection.AutofacRegistration.Populate,
从新实现了Autofac的同名扩展方法 Microsoft.Extensions.DependencyInjection.AutofacRegistration.Populateui
,他和原扩展方法相似但加入了新的逻辑,咱们不要引用错误包。this
跟踪其实现spa
public static void Populate( this ContainerBuilder builder, IServiceCollection services) { builder.RegisterType<AutofacServiceProvider>().As<IServiceProvider>(); builder.RegisterType<AutofacServiceScopeFactory>().As<IServiceScopeFactory>(); //注册IServiceProvider,IServiceScopeFactory Register(builder, services); }
private static void Register( ContainerBuilder builder, IServiceCollection services) { var moduleContainer = services.GetSingletonInstance<IModuleContainer>(); //植入的内容 var registrationActionList = services.GetRegistrationActionList(); //植入的内容 foreach (var service in services) { if (service.ImplementationType != null) { // Test if the an open generic type is being registered var serviceTypeInfo = service.ServiceType.GetTypeInfo(); if (serviceTypeInfo.IsGenericTypeDefinition) //IsGenericTypeDefinition 这个能够泛型类型判断是否参数实例化了 { builder .RegisterGeneric(service.ImplementationType) //注册一个无参数实例化的泛型类型 .As(service.ServiceType) .ConfigureLifecycle(service.Lifetime) .ConfigureAbpConventions(moduleContainer, registrationActionList); //这一步是新添加的逻辑 包含拦截器 } else { builder .RegisterType(service.ImplementationType) .As(service.ServiceType) .ConfigureLifecycle(service.Lifetime) .ConfigureAbpConventions(moduleContainer, registrationActionList); //这一步是新添加的逻辑 包含拦截器 } } else if (service.ImplementationFactory != null) { var registration = RegistrationBuilder.ForDelegate(service.ServiceType, (context, parameters) => { var serviceProvider = context.Resolve<IServiceProvider>(); return service.ImplementationFactory(serviceProvider); }) .ConfigureLifecycle(service.Lifetime) .CreateRegistration(); //TODO: ConfigureAbpConventions ? builder.RegisterComponent(registration); } else { builder .RegisterInstance(service.ImplementationInstance) .As(service.ServiceType) .ConfigureLifecycle(service.Lifetime); } } }
其主要逻辑是把serives中每个服务注册在builder中注册。其中对每一个服务还调用了ConfigureAbpConventions(moduleContainer, registrationActionList)设计
public static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> ConfigureAbpConventions<TLimit, TActivatorData, TRegistrationStyle>( //builder.Populate(services)植入的ABP部分 this IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> registrationBuilder, IModuleContainer moduleContainer, ServiceRegistrationActionList registrationActionList) where TActivatorData : ReflectionActivatorData { var serviceType = registrationBuilder.RegistrationData.Services.OfType<IServiceWithType>().FirstOrDefault()?.ServiceType; if (serviceType == null) { return registrationBuilder; //直接返回 } var implementationType = registrationBuilder.ActivatorData.ImplementationType; if (implementationType == null) { return registrationBuilder; //没有实现类型 直接返回 } registrationBuilder = registrationBuilder.EnablePropertyInjection(moduleContainer, implementationType); //当前type程序集包含Abp模块则开启属性注入 registrationBuilder = registrationBuilder.InvokeRegistrationActions(registrationActionList, serviceType, implementationType); //调用registration HOOK 若是有拦截器,则添加拦截器 return registrationBuilder; }
上面serviceType是Autofac的registrationBuilder添加的元数据咱们没必要理会,implementationType是组件(服务实例)类型。重点咱们跟踪下InvokeRegistrationActions代理
private static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> InvokeRegistrationActions<TLimit, TActivatorData, TRegistrationStyle>(this IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> registrationBuilder, ServiceRegistrationActionList registrationActionList, Type serviceType, Type implementationType) where TActivatorData : ReflectionActivatorData { var serviceRegistredArgs = new OnServiceRegistredContext(serviceType, implementationType); foreach (var registrationAction in registrationActionList) //执行每个registrationAction { registrationAction.Invoke(serviceRegistredArgs); } if (serviceRegistredArgs.Interceptors.Any()) //IMPORTANT 若是有拦截器,则添加拦截器 { registrationBuilder = registrationBuilder.AddInterceptors( serviceType, serviceRegistredArgs.Interceptors ); } return registrationBuilder; }
private static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> AddInterceptors<TLimit, TActivatorData, TRegistrationStyle>( this IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> registrationBuilder, Type serviceType, IEnumerable<Type> interceptors) where TActivatorData : ReflectionActivatorData { if (serviceType.IsInterface) { registrationBuilder = registrationBuilder.EnableInterfaceInterceptors(); //开启接口拦截器 } else { (registrationBuilder as IRegistrationBuilder<TLimit, ConcreteReflectionActivatorData, TRegistrationStyle>)?.EnableClassInterceptors(); //开启类拦截器 } foreach (var interceptor in interceptors) { registrationBuilder.InterceptedBy( //https://www.cnblogs.com/stulzq/p/8547839.html autofac的动态代理 Autofac.Extras.DynamicProxy程序集 typeof(CastleAbpInterceptorAdapter<>).MakeGenericType(interceptor) //范型类型实例化 ABP拦截器转CASTLE拦截器 ); } return registrationBuilder; }
动态代理实现使用的是Castle.Core的api中 code
public static IRegistrationBuilder<TLimit, TActivatorData, TStyle> InterceptedBy<TLimit, TActivatorData, TStyle>( this IRegistrationBuilder<TLimit, TActivatorData, TStyle> builder, params Type[] interceptorServiceTypes)
其中interceptorServiceTypes为IInterceptor的类型的Type。咱们Abp使用的是IAbpInterceptor。 CastleAbpInterceptorAdapter类就是实现从IAbpInterceptor到IInterceptor的适配。
public void Intercept(IInvocation invocation) //拦截器业务逻辑 Castle 的拦截器有一个 Intercept() 方法,该方法将在被拦截方法执行的时候触发。 { var proceedInfo = invocation.CaptureProceedInfo(); var method = invocation.MethodInvocationTarget ?? invocation.Method;// MethodInvocationTarget目标类方法的methodInfo, Method代理方法的methodInfo if (method.IsAsync()) { InterceptAsyncMethod(invocation, proceedInfo); } else { InterceptSyncMethod(invocation, proceedInfo); } }
private void InterceptSyncMethod(IInvocation invocation, IInvocationProceedInfo proceedInfo) { _abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation, proceedInfo)); }
看一下CastleAbpInterceptorAdapter类型的Intercept方法,又调用的是_abpInterceptor.Intercept方法。
由上面能够看出。咱们是经过CastleAbpInterceptorAdapter完成从castle core拦截器到abp拦截器的适配。 咱们定义好apb拦截器,abp自动为咱们生成对应的castle core拦截器进行适配,进行拦截时castle core拦截器调用咱们的apb拦截器的拦截接口void Intercept(IAbpMethodInvocation invocation);
以上是abp拦截器的实现机制。经过CastleAbpInterceptorAdapter适配层完成调用castle core拦截器到间接调用 abp拦截器的转换。