• Asp.net Core AOP实现(采用Autofac)


    引用正确的库来实现AOP

    新的.NET Core是基于.NET Standard的..所以我们在引用库的时候特别要注意相关的兼容问题.
    在传统的ASP.NET中,使用过Autofac来进行AOP操作的,应该都知道这个库.
    Autofac.Extras.DynamicProxy

    添加Nuget包:Autofac.Extras.DynamicProxy

    定义一个拦截器类,实现IInterceptor

        public class TestInterceptor : IInterceptor
        {
            public void Intercept(IInvocation invocation)
            {
                Console.WriteLine("你正在调用方法 "{0}"  参数是 {1}... ",
                    invocation.Method.Name,
                    string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));
    
                invocation.Proceed();
    
                Console.WriteLine("方法执行完毕,返回结果:{0}", invocation.ReturnValue);
            }
        }
    

    这里,需要继承IInterceptor,然后实现它的Intercept方法。我们直接将拦截内容输出到调试窗(正式项目请根据业务来操作拦截)。

    修改Startup的ConfigureContainer方法

    • 拦截器注册要在使用拦截器的接口和类型之前
    public void ConfigureDevelopmentContainer(ContainerBuilder builder)
    {
        // 要先注册拦截器
        builder.RegisterType<TestInterceptor>();
    
        builder.RegisterType<TopicService>().As<ITopicService>().EnableInterfaceInterceptors();
    
        //如果需要在Controller中使用属性注入,需要在ConfigureContainer中添加如下代码
        var controllerBaseType = typeof(ControllerBase);
    
        builder.RegisterAssemblyTypes(typeof(Program).Assembly)
            .Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
            .PropertiesAutowired()//允许属性注入
            .EnableClassInterceptors();// 允许在Controller类上使用拦截器
    }
    

    这里注意,一定要在你注入的服务后面加上EnableInterfaceInterceptors来开启你的拦截

    在需要使用拦截器的类或接口上添加描述

    [Intercept(typeof(TestInterceptor))]
    
    1. 自定义服务上使用拦截器
      我这里是定义了一个接口,如下:
    [Intercept(typeof(TestInterceptor))]
    public interface ITopicService
    {
        int Add(int a, int b);
    }
    

    定义一个实现接口的类

     public class TopicService:ITopicService
        {
            public int Add(int a,int b)
            {
                return a + b;
            }
        }
    

    然后我们运行代码.
    效果如下:

    1. 在Controller上使用拦截器
    [Intercept(typeof(TestInterceptor))]
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        private readonly ITopicService _service;
    
        public HomeController(ILogger<HomeController> logger,ITopicService service)
        {
            _logger = logger;
            _service = service;
        }
    
        public IActionResult Index()
        {
            return View();
        }
    }
    

    这样,我们就完成了使用Autofac进行AOP拦截。
    Autofac的AOP拦截器还有很多功能与用法.我这里就不一一举例了。

    其实asp.net core自带的过滤器也够用了,这里只是记录下不同的实现方式。

    动态代理的高级用法

    一个接口多个实现

    AspNetCore3.0中

    public interface ITestUtil
    {
        void Show(string content);
    }
     
    public class TestUtil1 : ITestUtil
    {
        public void Show(string content)
        {
            Console.WriteLine("TestUtil1:" + content);
        }
    }
     
    public class TestUtil2 : ITestUtil
    {
        public void Show(string content)
        {
            Console.WriteLine($"TestUtil2:{content}");
        }
    }
    

    别忘了在Startup中注册服务

    builder.RegisterType<TestUtil1>().As<ITestUtil>();
    builder.RegisterType<TestUtil2>().As<ITestUtil>();
    

    在控制器中使用

    // 默认情况下,构造函数注入和属性注入的结果都是最后注册的那个实现,
    // 也就是TestUtil2
    private readonly ITestUtil _util;
     
    public HomeController(ITestUtil util, IServiceProvider provider)
    {
        _util = util;
        // 如果知道注册的顺序,可以用这种方式,
        // 第一个注册是TestUtil1,所以这里返回TestUtil1
        var util1 = provider.GetServices<ITestUtil>().ElementAtOrDefault(0);
        util1?.Show("指定注册为ITestUtil的第一个实现");
        
        // 一般情况下用这种方式,指定成具体的类型 TestUtil1
        var utilFirst = provider.GetServices<ITestUtil>()
            .SingleOrDefault(t => t.GetType() == typeof(TestUtil1));
        util1?.Show("指定名称为TestUtil的实现");
    }
    

  • 相关阅读:
    SPOJ GSS4 Can you answer these queries IV ——树状数组 并查集
    SPOJ GSS3 Can you answer these queries III ——线段树
    SPOJ GSS2 Can you answer these queries II ——线段树
    SPOJ GSS1 Can you answer these queries I ——线段树
    BZOJ 2178 圆的面积并 ——Simpson积分
    SPOJ CIRU The area of the union of circles ——Simpson积分
    HDU 1724 Ellipse ——Simpson积分
    HDU 1071 The area ——微积分
    HDU 4609 3-idiots ——FFT
    BZOJ 2194 快速傅立叶之二 ——FFT
  • 原文地址:https://www.cnblogs.com/zhanwei103/p/13151587.html
Copyright © 2020-2023  润新知