[原创]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.如果可以实现特性就更优雅了

时间: 2024-11-10 01:12:28

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

netcore 2.2 使用 Autofac 实现自动注入

Autofac自动注入是通过名称约定来实现依赖注入 ps:本demo接口层都以“I”开头,以“Service”结尾.服务层实现都以“Service”结尾. 为什么要实现自动注入 大多时候,我们都是 以下方式进行依赖注入 public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Vers

五)Spring + Quartz 复杂业务的两个问题:获取Spring上下文 和 自动注入服务类

配置如下: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/

解决Autofac MVC 自动注入在 Areas拆分到不同dll下的注入失败问题走奏谞踪昨兹

position:static(静态定位) 当position属性定义为static时,可以将元素定义为静态位置,所谓静态位置就是各个元素在HTML文档流中应有的位置 podisition定位问题.所以当没有定义position属性时,并不说明该元素没有自己的位置,它会遵循默认显示为静态位置,在静态定位状态下无法通过坐标值(top,left,right,bottom)来改变它的位置. position:absolute(绝对定位) 当position属性定义为absolute时,元素会脱离文档流

[Solution] AOP原理解析及Castle、Autofac、Unity框架使用

AOP介绍 面向切面编程(Aspect Oriented Programming,英文缩写为AOP),通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. AOP是OOP的延续,是软件开发中的一个热点. 常用于: Authentication Caching Lazy loading Transactions AOP基本原理 普通类 1 2 3 4 5 6 7 8 9 class Person : MarshalByRefObject {     public string Say(

ASP.NET MVC Autofac自动注入

依赖注入容器有很多插件,我用过Unity和Autofac,这两个插件给我最明显的感觉就是Autofac很快,非常的快,毕竟是第三方开发的,而Unity相对而言性能比较稳定 下面附上Autofac自动注入代码:(IDependency接口表示要注入的接口必须要继承它,WEB中必须要添加接口类库和接口实现类库,否则会注入失败),其实原理就是反射 using System.Linq; using System.Reflection; using System.Web.Compilation; usin

原创001 | 搭上SpringBoot自动注入源码分析专车

前言 如果这是你第二次看到师长的文章,说明你在觊觎我的美色!O(∩_∩)O哈哈~ 点赞+关注再看,养成习惯 没别的意思,就是需要你的窥屏^_^ 本系列为SpringBoot深度源码专车系列,第一篇发车! 专车介绍 该趟专车是开往Spring Boot自动注入原理源码分析的专车 专车问题 Spring Boot何时注入@Autowired标注的属性? 如果注入类型的Bean存在多个Spring Boot是如何处理的? 专车示例 定义接口 public interface PersonService

NET Core源代码通过Autofac实现依赖注入

查看.NET Core源代码通过Autofac实现依赖注入到Controller属性 阅读目录 一.前言 二.使用Autofac 三.最后 回到目录 一.前言 在之前的文章[ASP.NET Core 整合Autofac和Castle实现自动AOP拦截]中,我们讲过除了ASP.NETCore自带的IOC容器外,如何使用Autofac来接管IServiceProvider进行依赖注入. 最近老有想法在ASP.NET Mvc Core中实现Controller的属性值的依赖注入,但是找遍了Micros

Autofac 的属性注入,IOC的坑

Autofac 是一款优秀的IOC的开源工具,完美的适配.Net特性,但是有时候我们想通过属性注入的方式来获取我们注入的对象,对不起,有时候你还真是获取不到,这因为什么呢? 1.你对Autofac 不太了解,在这个浮躁的社会,没有人会认真的了解每个开源项目,只要求能用就行 2.没有时间了解,你是一个很忙的人,工作很忙,应酬很忙 3.刚开始使用Autofac 还没来得及深入了解就要做项目. 不管是什么原因,总之我们注入的属性就是无法直接由autofac 自动注入,或者说我们希望由Autofac自动

NopCommerce使用Autofac实现依赖注入

NopCommerce的依赖注入是用的AutoFac组件,这个组件在nuget可以获取,而IOC反转控制常见的实现手段之一就是DI依赖注入,而依赖注入的方式通常有:接口注入.Setter注入和构造函数注入. NopCommerce将所有和Autofac注入相关的工作都放到了EngineContext中,在Global.asax的Application_Start函数的第一句代码即是: //initialize engine context EngineContext.Initialize(fal