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的實現");
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM