最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

ASP.NET Core 奇淫技巧之偽屬性注入的實現

 更新時間:2020年08月14日 10:49:53   作者:曉晨Master  
這篇文章主要介紹了ASP.NET Core 奇淫技巧之偽屬性注入的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一.前言

開局先嘮嗑一下,許久未曾更新博客,一直在調整自己的狀態(tài),去年是我的本命年,或許是應驗了本命年的多災多難,過得十分不順,不論是生活上還是工作上。還好當我度過了所謂的本命年后,許多事情都在慢慢變好,我將會開始恢復更新博客,爭取恢復到以前的速度上(因為工作比較忙,所以這個過程可能需要一段時間)。

二.關于屬性注入

說到屬性注入,我們就不得不提一下 DI(Dependency Injection),即依賴注入,用過 ASP.NET Core 的同學相信對這個詞不會陌生。ASP.NET Core 自帶了一個IOC容器,且程序運行也是基于這個容器建立起來的,在 Startup 里的 ConfigureServices 方法就是向容器注冊類型。最直白的講,我們在 ASP.NET Core 中,想使用某個類型的時候可以不用自己去 new,可以由容器通過構造方法來注入具體的實現類型,而我們一般在構造方法上定義的依賴類型都是接口,而不是去依賴具體的實現,這里就體現了 SOLID 原則中的依賴倒置原則(DIP)。這也是IOC(Inversion of Control),即控制反轉,不直接依賴具體實現,將依賴交給容器去控制。上述幾者是具有一定的關聯關系的,DIP 是一種軟件設計原則,IOC 是 DIP 的具體實現方式,DI 是 IOC 的一種實現方式。

在依賴注入時,我們最常用的便是通過構造方法注入,還有另一種方式那便是屬性注入。

關于屬性注入,如果在網上搜索,大部分內容都是不推薦使用,或者說慎重使用的,因為屬性注入會造成類型的依賴關系隱藏,測試不友好等,我也同意這種說法,屬性注入可以使用,但是要謹慎,不能盲目使用。我的原則:在封裝框架(搭架子)時可以使用,但不能大范圍使用,只有必須使用屬性注入來達到效果的地方才會使用,用來提高使用框架時的編碼效率,來達到一些便利,脫離框架層面,編寫業(yè)務代碼時,不得使用。

在 ASP.NET Core 中,自帶的容器是不支持屬性注入的,但是可以通過替換容器,如:Autofac 等來實現。今天我分享的方法不是使用替換容器,而是通過幾行代碼來實現屬性注入的效果,我稱為“偽屬性注入”。

三.屬性注入解決的痛點

以下介紹的痛點是我在實際編碼過程中遇到的一些,如果還有其他的,歡迎在評論和我交流

我所遇到的痛點,我歸納為三條:

1.減少常用的類型的重復注入代碼,使構造方法看起來更為簡潔,提高閱讀性。

2.減少或消除因構造方法注入造成子類繼承后的 base 調用鏈。

3.并非是滿足第一條或第二條就需要使用屬性注入來解決,只有當第一、二條發(fā)生的情況到達一定的數量。

第一條:

以日志 ILogger<T> 為例,我們在 Controller 或者 應用服務層(Application Service)等編寫業(yè)務的地方可能會常用,那么我們可能會在大部分的 Controller 或者 Application Service 的構造方法里寫一句注入,例:

這里只是以日志來舉例,我們還能遇到和日志這種相同的類型,每個 Controller 等都要注入一堆這種共同的類型,代碼編寫起來也比較麻煩,如果多了以后還影響代碼閱讀。

有何解決辦法,那就是定義一個基類,然后通過屬性提供給子類,以 Controller 為例:

第二條:

在上面的Controller基類注入 ILogger,然后設置了 Logger 屬性,這樣子類就可以使用 Logger 屬性來使用日志。

這樣做每次都要調用 base 將依賴對象傳遞給基類,如果繼承關系有多層,將會造成更大的影響。

注意:本文演示只以日志來舉例,如果只有一個ILogger我覺得還可以忍受,實際情況中并非只有一個,比如本地化等等。博主不提倡有上面演示情況的就用屬性注入,當到達一定數量才使用,比如在 Controller 或者應用服務這種數量多的對象以及當這些對象需要的共同的注入類型達到一定數量。

四. 偽屬性注入核心思想

依托于 ASP.NET Core 自帶的容器,在 Resolve Service 時,為需要“屬性注入”的屬性進行賦值,可以使用 自帶容器提供的 ImplementationFactory 來實現。

五. 為 Controller 實現偽屬性注入

Controller 的實現較為特殊,Controller 默認是不會通過自帶容器來 Resolve&Activate 的,是通過MVC自身管理的,但是微軟提供了這樣的方法:

services.AddControllers().AddControllersAsServices();

可以通過調用 AddControllersAsServices() 方法來讓 Controller 使用自帶容器,其主要源代碼如下

根據第四小節(jié)的思想,我們需要 Controller Resolve 時,來對屬性進行賦值,那么我們需要改造 Controller 激活器。

定義 Controller 基類

Controller 繼承基類

改造 Controller 激活器

可以看到我們改造的代碼也就幾行。

替換默認 Controller 激活器

services.AddControllers().AddControllersAsServices();
services.Replace(ServiceDescriptor.Transient<IControllerActivator, XcServiceBasedControllerActivator>()); 
//替換默認 Controller 激活器

運行測試

測試正常,如需其他屬性的“屬性注入”,參考日志這樣做就行了。

六. 為 Application Service 實現偽屬性注入

只是以 Application Service 來作為講解,同理可舉一反三到其他地方。Application Service 屬于領域驅動分層架構中的一層,如不了解,可自行查找資料。

定義應用服務基類接口

public interface IAppService
{
  ILogger Logger { get; set; }
}

public class AppService:IAppService
{
  public ILogger Logger { get; set; }
}

定義具體服務,以 User 服務為例

public interface IUserAppService:IAppService
{
  void Create();
}

public class UserAppService : AppService,IUserAppService
{
  public void Create()
  {
    Logger.LogInformation("來自 Application Service 的日志");
  }
}

定義特殊的注冊服務的方法,以便實現 Resolve 為 Logger 賦值

public static class ServiceExtensions
{
  public static IServiceCollection AddApplicationService<TService, TImpl>(this IServiceCollection services) where TService:IAppService where TImpl:AppService
  {
    services.AddApplicationService(typeof(TService), typeof(TImpl));
    return services;
  }
  // 可以反射程序集調用此方法實現批量自動注冊應用服務
  public static IServiceCollection AddApplicationService(this IServiceCollection services, Type serviceType,Type implType)
  {
    services.AddTransient(serviceType, sp =>
    {
      //獲取服務實現的實例
      var implInstance = ActivatorUtilities.CreateInstance(sp, implType); ;

      if (implInstance is AppService obj)
      {
        //為 Logger 賦值
        obj.Logger= sp.GetRequiredService<ILoggerFactory>().CreateLogger(implType);
      }
      
      return implInstance;
    });
    return services;
  }

注冊測試服務

Controller 注入測試服務

運行測試

七.結束

其實到本文寫完,我都在想,要不要封裝一個組件,發(fā)布到 Nuget 來方便的使用文中我所描述的“偽屬性注入”,最后反復想了想,還是覺得不做。如果要使用完全的屬性注入可以替換使用第三方容器,本文所述旨在不想引入第三方容器,且想在部分地方來達到屬性注入的效果,因為屬性注入這個東西也不推薦大范圍使用。

本文來源于我在工作中的一些靈感總結,我在看 ControllerActivator 源碼時的突發(fā)奇想,最近工作雖然忙,但是知識確實積攢了不少,在后面與大家一一分享。

姊妹篇:ASP.NET Core 奇淫技巧之動態(tài)WebApi

到此這篇關于ASP.NET Core 奇淫技巧之偽屬性注入的實現的文章就介紹到這了,更多相關ASP.NET Core 偽屬性注入內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

作者:曉晨Master(李志強)

文章鏈接:https://www.cnblogs.com/stulzq/p/12610026.html

相關文章

最新評論

东乡族自治县| 平安县| 张家港市| 中超| 齐齐哈尔市| 鄂托克前旗| 康马县| 浮梁县| 志丹县| 临汾市| 巴林左旗| 邮箱| 晋宁县| 苗栗县| 高雄市| 武汉市| 洪湖市| 都兰县| 延长县| 咸阳市| 都匀市| 开封市| 鸡西市| 甘谷县| 海南省| 阜南县| 固阳县| 旺苍县| 乌兰浩特市| 张家口市| 彰武县| 侯马市| 东乌珠穆沁旗| 常熟市| 平山县| 济阳县| 城步| 乳山市| 合江县| 榆林市| 自贡市|