动态代理

反射机制:程序运行时自省的能力,通过反射操作类与对象,获取对象的类定义,类声明的属性与方法,调用方法与构造对象,甚至在运行时修改类的定义。

动态代理:是一种方便运行时动态构建代理,动态处理代理方法调用机制。代理是对调用目标的一个包装,对目标代码不是直接发生,而是通过代理发生,

动态代理,很多情况可以看作是装饰器的一个运用,反射是实现的一种常用的方式。

 

Autofac与Castle.DynamicProxy实现AOP功能

1、定义拦截器,实现 Castle.DynamicProxy.IInterceptor 

public interface IInterceptor
{
    void Intercept(IInvocation invocation);
}

其中:IInvocation的接口的方法,invocation.Arguments是数组,args[0]是第一个参数

invocation.Proceed(); // 调用下一个拦截器,直到最终的目标方法。

定义好了拦截器后,如何应用到相关对象呢?有两种方式:

     1)使用 Autofac.Extras.DynamicProxy.InterceptAttribute 特性将拦截器添加到相关的类或接口上;
     2)使用 ContainerBuilder 的 InterceptedBy() 方法在注册对象的同时添加拦截器。
 
基于接口的拦截器
   在注册对象的同时启用 EnableInterfaceInterceptors() 方法。
基于类的拦截器

      在注册对象的同时启用 EnableClassInterceptors() 方法。

比如:注册两个拦截器,然后通过autofac 的Ioc容器,实现Resolve服务,执行顺序:CalculaterInterceptor  --> CalculaterInterceptor2 --> Target Method --> CalculaterInterceptor2 --> CalculaterInterceptor 。拦截器中 invocation.Proceed() 方法用于调用下一个拦截器(若存在),直到最终的目标方法(Target Method)。不过 invocation.Proceed() 并不是一定要调用的,例如,对于有返回值的目标方法,我们在拦截器中设置 invocation.ReturnValue 值就可正确执行,这样便不会执行目标方法。在有些场景中,如身份验证、缓存读取等还是特别有用

 var builder = new ContainerBuilder();
            builder.RegisterType<Calculater>()
                .As<ICalculater>()
                .EnableInterfaceInterceptors()
                .InterceptedBy(typeof(CalculaterInterceptor), typeof(CalculaterInterceptor2));  // 这里定义了两个拦截器,注意它们的顺序

            builder.RegisterType<CalculaterInterceptor>();  // 注册拦截器
            builder.RegisterType<CalculaterInterceptor2>();  // 注册拦截器2

            var ioc = builder.Build();

            var calculater = ioc.Resolve<ICalculater>();
            var addResult = calculater.Add(2, 3);

            Console.WriteLine($"add result: {addResult}");

另外:接口上以特性的形式注册,如上面代码中注释掉的那部分。若是既有在类型上注册,也有在 Autofac 的 Builder 中注册,那么这个拦截器会重复执行。

非虚方法,所有拦截器不会在该方法中调用。

 

在ABP vnext的实现方式,在服务自动注册模块,首先根据 实现类型ImplementationType(是class,不是接口,抽象类,泛型类),检查生命周期、servicesType注册在SerivceCollection里面,OnExposing定义ImplementationType的ExposedTypes,,可自定义委托函数OnRegistred,定义ImplementationType的Interceptors、

在注入Autofac容器

AbpAsyncDeterminationInterceptor<>的泛型参数才是用户定义的拦截器, interceptor:IAbpIntercepor

if (serviceType.IsInterface)
            {
                registrationBuilder = registrationBuilder.EnableInterfaceInterceptors();
            }
            else
            {
                (registrationBuilder as IRegistrationBuilder<TLimit, ConcreteReflectionActivatorData, TRegistrationStyle>)?.EnableClassInterceptors();
            }

            foreach (var interceptor in interceptors)
            {
                registrationBuilder.InterceptedBy(
                    typeof(AbpAsyncDeterminationInterceptor<>).MakeGenericType(interceptor)
                );
            }

AsyncDeterminationInterceptor(IAsyncInterceptor) 

CastleAsyncAbpInterceptorAdapter<TInterceptor>(TInterceptor)需要用户定义的拦截器,的泛型参数, TInterceptor : IAbpInterceptor

这里有个IAbpMethodInvocation的实现CastleAbpMethodInvocationAdapter(invocation, proceedInfo, proceed),CastleAbpMethodInvocationAdapterWithReturnValue

https://github.com/JSkimming/Castle.Core.AsyncInterceptor

 

关于特性

1、Dependency特性,它拥有ServiceLifeTime,TryRegister,ReplaceServices属性

ExploseService特性,同时实现IExplosedServiceTypesProvider对外暴露的ServiceTypes类型,是对包括InclueDefault(即包括默认接口,I开头,默认结尾)IncludeSelf( 包括自己)

 

type.GetCustomAttribute<DependencyAttribute>(true);

 private static readonly ExposeServicesAttribute DefaultExposeServicesAttribute =
            new ExposeServicesAttribute
            {
                IncludeDefaults = true,
                IncludeSelf = true
            };

        public static List<Type> GetExposedServices(Type type)
        {
            return type
                .GetCustomAttributes()
                .OfType<IExposedServiceTypesProvider>()
                .DefaultIfEmpty(DefaultExposeServicesAttribute)
                .SelectMany(p => p.GetExposedServiceTypes(type))
                .ToList();
        }

 

 public static List<Type> FindDependedModuleTypes(Type moduleType)
        {
            AbpModule.CheckAbpModuleType(moduleType);

            var dependencies = new List<Type>();

            var dependencyDescriptors = moduleType
                .GetCustomAttributes()
                .OfType<IDependedTypesProvider>();

            foreach (var descriptor in dependencyDescriptors)
            {
                foreach (var dependedModuleType in descriptor.GetDependedTypes())
                {
                    dependencies.AddIfNotContains(dependedModuleType);
                }
            }
            return dependencies;
        }

 

public static UnitOfWorkAttribute GetUnitOfWorkAttributeOrNull(getmethodInfo)
        {
            var attrs = methodInfo.GetCustomAttributes(true).OfType<UnitOfWorkAttribute>().ToArray();
            if (attrs.Length > 0)
            {
                return attrs[0];
            }

            attrs = methodInfo.DeclaringType.GetTypeInfo().GetCustomAttributes(true).OfType<UnitOfWorkAttribute>().ToArray();
            if (attrs.Length > 0)
            {
                return attrs[0];
            }
            
            return null;
        }
        
        private static bool AnyMethodHasUnitOfWorkAttribute(TypeInfo implementationType)
        {
            return implementationType
                .GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                .Any(HasUnitOfWorkAttribute);
        }

        private static bool HasUnitOfWorkAttribute(MemberInfo methodInfo)
        {
            return methodInfo.IsDefined(typeof(UnitOfWorkAttribute), true);
        }

 

     

 

 

 

 

posted on 2019-11-04 09:59  dollymi  阅读(743)  评论(0编辑  收藏  举报

导航