[原创]Aop之使用Autofac+Castle 自动注入服务且动态代理服务实现拦截

Posted zslm___

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[原创]Aop之使用Autofac+Castle 自动注入服务且动态代理服务实现拦截相关的知识,希望对你有一定的参考价值。

public static class AutofacComponentManualRegister
    {
        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="builder">bundles</param>
        public static IContainer RegisterIOC()
        {
            ContainerBuilder builder = new ContainerBuilder();
            //构造函数注入
            builder.RegisterAssemblyTypes(Assembly.GetCallingAssembly()).AsImplementedInterfaces();
            //注入控制器并实现属性注入
            builder.RegisterControllers(Assembly.GetCallingAssembly());
            //支持过滤器的属性注入-
            builder.RegisterFilterProvider();

            builder.RegisterType<MemoryCacheProvider>().As<ICacheProvider>().SingleInstance();
            builder.RegisterType<AppService>().As<IAppService>().EnableAop(typeof(IAppService));
            builder.RegisterType<ProductService>().As<IProductService>().SingleInstance();
            builder.RegisterType<CustomerService>().As<ICustomerService>().SingleInstance();
            builder.RegisterType<UserService>().As<IUserService>().SingleInstance();
            var registration = builder.RegisterType<SaleOrderService>().As<ISaleOrderService>().SingleInstance();



            var container = builder.Build();


            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));


            return container;
        }

        private static void EnableAop<TLimit, TActivatorData, TSingleRegistrationStyle>(this IRegistrationBuilder<TLimit, TActivatorData, TSingleRegistrationStyle> registrationBuilder,Type type)
        {
            registrationBuilder.RegistrationData.ActivatingHandlers.Add((sender, e) =>
            {
                try
                {
                    e.Instance = proxyGenerator.CreateInterfaceProxyWithTarget(type, e.Instance, new LogInterceptor());
                }
                catch (Exception ex)
                {

                }
            });
        }

        static readonly ProxyGenerator proxyGenerator = new ProxyGenerator();
}

 

2.拦截类

public class LogInterceptor : IInterceptor
    {
        /// <summary>
        /// logger
        /// </summary>
        private static readonly ILog Logger = LogManager.GetLogger(typeof(LogInterceptor));

        public LogInterceptor()
        {
        }
        public void Intercept(IInvocation invocation)
        {
            var request = JsonConvert.SerializeObject(invocation.Arguments);
            if (invocation.Arguments.Length > 0 && invocation.Arguments[0] is Request)
            {
                Logger.DebugFormat("请求服务名:{0} 方法名:{1} 请求参数:{2}", invocation.TargetType, invocation.Method.Name, request);
                invocation.Proceed();
                var resp = invocation.ReturnValue;
                var response = JsonConvert.SerializeObject(resp);
                Logger.DebugFormat("请求服务名:{0} 方法名:{1} 返回参数:{2}", invocation.TargetType, invocation.Method.Name, response);
            }
            else
            {
                invocation.Proceed();
                Logger.ErrorFormat("非法请求:{0}",request);
            }
        }
    }

 

3.

/// <summary>
    /// IAppService
    /// </summary>
    [ServiceContract]
    public interface IAppService
    {
        /// <summary>
        /// APP后端获取标接口
        /// </summary>
        /// <returns></returns>
        [OperationContract]
        IsAliveResp IsAlive(IsAliveReq req);

        
    }

 

4.

public class AppService : IAppService
    {
        #region field
        /// <summary>
        /// IBatis访问DB接口
        /// </summary>
        private readonly ISqlMapper _mapper;

        /// <summary>
        /// logger
        /// </summary>
        private static readonly ILog Logger = LogManager.GetLogger(typeof(AppService));
        #endregion

        #region .ctor
        /// <summary>
        /// App服务接口(对App端)
        /// </summary>
        public AppService()
        {
            this._mapper = SqlMap.Instance();
        }
        #endregion

        #region public

        /// <summary>
        /// 获取商品列表
        /// </summary>
        /// <returns></returns>
        public IsAliveResp IsAlive(IsAliveResp req)
        {
            var result = this._mapper.QueryForObject<DateTime>("queryCurrentTimeFromDatabase", null);

            return new IsAliveResp()
            {
                Success = true,
                Time = result.ToString("yyyy-MM-dd HH:mm:ss.fff")
            };
        }
}

 

对EnableAop改进,支持自动获取相应的接口类,并传入拦截器数组

 private static void EnableAop<TLimit, TActivatorData, TSingleRegistrationStyle>(this IRegistrationBuilder<TLimit, TActivatorData, TSingleRegistrationStyle> registrationBuilder,params IInterceptor[] types)
        {
            registrationBuilder.RegistrationData.ActivatingHandlers.Add((sender, e) =>
            {
                try
                {
                    var serviceWithTypes =
                        e.Component.Services.OfType<IServiceWithType>().Select(x => x.ServiceType).ToList();
                    if (serviceWithTypes.Count == 1)
                    {
                        e.Instance = proxyGenerator.CreateInterfaceProxyWithTarget(serviceWithTypes[0], e.Instance, types);
                    }
                    
                }
                catch (Exception ex)
                {

                }
            });
        }

 

5.对于wcf服务无法调用控制器的拦截器(ActionFilter),所以可以调用该服务时就自动实现了拦截

6.下一步改进,在EnableAop()里可以无需传入类型参数,而代替的是IInterceptor[] 参数

7.如果可以实现特性就更优雅了

以上是关于[原创]Aop之使用Autofac+Castle 自动注入服务且动态代理服务实现拦截的主要内容,如果未能解决你的问题,请参考以下文章

[Asp.Net Core]Autofac抽象支持AOP

[Asp.Net Core]Autofac抽象支持AOP

切面编程AOP之Castle.Core

Autofac + Castle DynamicProxy:拦截器的顺序

依赖反转Ioc和unity,autofac,castle框架教程及比较

什么是面向切面编程AOP