日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET Core - 在ActionFilter中使用依赖注入

發布時間:2023/12/4 asp.net 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET Core - 在ActionFilter中使用依赖注入 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上次ActionFilter引發的一個EF異常,本質上是對Core版本的ActionFilter的知識掌握不夠牢固造成的,所以花了點時間仔細閱讀了微軟的官方文檔。發現除了IActionFilter、IAsyncActionFilter的問題,還有一個就是依賴注入在ActionFilter上的使用也是需要注意的地方。
當我們的ActionFilter需要使用某個Service的時候,我們一般會通過構造函數注入。
演示一下,首先自定義一個ActionFilter,通過構造函數注入IMyService:

public interface IMyService{string GetServiceName(); }public class MyService : IMyService{public MyService (){Console.WriteLine("Service {0} created .", GetServiceName());}public string GetServiceName(){return "MyService";}}public class FilterInjectAttribute: ActionFilterAttribute{public FilterInjectAttribute(IMyService myService){if (myService == null){throw new ArgumentNullException("myService");}Console.WriteLine("Service {0} was injected .", myService.GetServiceName());}}

但是我們在使用Attribute的時候VS直接給出紅色提示,需要傳入構造函數的參數,否則無法編譯過去。

當然我們可以直接new一個MyService來當做參數,但是很顯然這樣就失去了注入的那些好處了。

在ActionFilter中使用依賴注入

在ASP.NET Core的ActionFilter中使用依賴注入主要有兩種方式:

  • ServiceFilterAttribute

  • TypeFilterAttribute

  • ServiceFilterAttribute

    使用ServiceFilterAttribute可以使你的ActionFilter完成依賴注入。其實就是把你要用的ActionFilter本身注冊為一個Service注冊到DI容器中。通過ServiceFilter從容器中檢索你的ActionFilter,并且注入到需要的地方。所以第一步就是要注冊你的ActionFilter:

    public void ConfigureServices(IServiceCollection services){services.AddScoped<IMyService,MyService>();services.AddScoped(typeof(FilterInjectAttribute));services.AddControllers();services.AddRazorPages();}

    然后新建一個Controller,在Action上使用ServiceFilter:

    [ServiceFilter(typeof(FilterInjectAttribute))]public string DI(){Console.WriteLine("HomeController method DI running .");return "DI";}

    運行一下,在瀏覽器里訪問下對應的path,可以看到MyService已經注入到FilterInjectAttribute中:

    ServiceFilterAttribute的IsReusable屬性:

    ServiceFilter有一個屬性叫IsReusable。從字面意思也很好理解,就是是否可重用的意思。顯而易見如果這個屬性設置為True,那么多個請求就會復用這個ActionFilter,這就有點像是單例的意思了。

    [ServiceFilter(typeof(FilterInjectAttribute), IsReusable = true)]public string DI(){Console.WriteLine("HomeController method DI running .");return "DI";}

    運行一下,多次在瀏覽器中訪問對應的action的path,可以看到FilterInjectAttribute的構造函數只會執行一次。

    這里有一個重要提示, ASP.NET Core runtime 并不保證這個filter是真正的單例。所以不要試圖使用這個屬性來實現單例,并且業務系統依賴這個單例。

    TypeFilterAttribute

    使用TypeFilterAttribute也可以使你的ActionFilter完成依賴注入。它跟ServiceFilterAttribute差不多,但是使用TypeFilterAttribute注入的ActionFilter并不從DI容器中查找,而是直接通過Microsoft.Extensions.DependencyInjection.ObjectFactory來實例化對象。所以我們的FilterInjectAttribute不需要提前注冊到DI容器中。首先注釋掉FilterInjectAttribute的注冊代碼:

    public void ConfigureServices(IServiceCollection services){services.AddScoped<IMyService,MyService>();//services.AddScoped(typeof(FilterInjectAttribute));services.AddControllers();services.AddRazorPages();}

    改用TypeFilterAttribute:

    [TypeFilter(typeof(FilterInjectAttribute))]public string DI(){Console.WriteLine("HomeController method DI running .");return "DI";}

    運行一下,在瀏覽器里訪問下對應的path,可以看到MyService已經注入到FilterInjectAttribute中:

    TypeFilterAttribute的IsReusable屬性:

    跟上面的ServiceFilter一樣,ASP.NET Core runtime 并不保證這個filter是真正的單例,這里就不多啰嗦了。

    TypeFilterAttribute的Arguments屬性:

    Arguments參數是TypeFilterAttribute跟ServiceFilterAttribute的一個重要區別,ServiceFilterAttribute并沒有這屬性。Arguments類型為object數組。通過TypeFilterAttribute實例化的ActionFilter,如果它的構造器中的參數類型在DI容器中找不到,會繼續在Arguments參數列表里按順序獲取。
    改一下FilterInjectAttribute構造器多加入2個參數,并且保證這2個參數無法從DI中取到:

    public class FilterInjectAttribute: ActionFilterAttribute{public FilterInjectAttribute(string arg1, IMyService myService, string arg2){if (myService == null){throw new ArgumentNullException("myService");}Console.WriteLine("Service {0} was injected .", myService.GetServiceName());Console.WriteLine("arg1 is {0} .", arg1);Console.WriteLine("arg2 is {0} .", arg2);Console.WriteLine("FilterInjectAttribute was created .");}}

    在使用的時候傳入兩個參數:

    [TypeFilter(typeof(FilterInjectAttribute), Arguments = new object[] { "HAHA", "HOHO" })]public string DI(){Console.WriteLine("HomeController method DI running .");return "DI";}

    運行一下看到兩個參數被傳入了FilterInjectAttribute的構造器:

    總結

  • ActionFilterAttribute的依賴注入可以通過ServiceFilterAttribute,TypeFilterAttribute來實現

  • ServiceFilterAttribute是通過DI容器來管理ActionFilterAttribute;TypeFilterAttribute則是通過一個工廠直接實例化,所以使用前不需要注冊到DI容器中。

  • IsReusable屬性可以實現類似單例的功能,但是運行時并不保證唯一單例。

  • TypeFilterAttribute的Arguments屬性可以作為參數列表。當實例化ActionFilterAttribute的時候如果構造器參數類型沒有在DI容器中注冊那么會嘗試從Arguments列表中取。

  • 關注我的公眾號一起玩轉技術

    總結

    以上是生活随笔為你收集整理的ASP.NET Core - 在ActionFilter中使用依赖注入的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。