zoukankan      html  css  js  c++  java
  • 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的实现");
    }
    

  • 相关阅读:
    MongoDB导入数据库异常——Failed: cannot decode array into a D
    Unity中实现文字竖排的方法
    MongoDB基础
    基于Vuforia的Unity增强现实应用开发
    Windows设置自动关机
    开源软件的License科普
    87版《红楼梦》与原著回目对应表
    WCF初探-23:WCF中使用Message类(下)
    WCF初探-22:WCF中使用Message类(上)
    WCF初探-21:WCF终结点(endpoint)
  • 原文地址:https://www.cnblogs.com/zhanwei103/p/13151587.html
Copyright © 2011-2022 走看看