成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

ASP.NETCore怎么實(shí)現(xiàn)偽屬性注入-創(chuàng)新互聯(lián)

一.前言

成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作,成都做網(wǎng)站公司-創(chuàng)新互聯(lián)建站已向成百上千企業(yè)提供了,網(wǎng)站設(shè)計(jì),網(wǎng)站制作,網(wǎng)絡(luò)營銷等服務(wù)!設(shè)計(jì)與技術(shù)結(jié)合,多年網(wǎng)站推廣經(jīng)驗(yàn),合理的價(jià)格為您打造企業(yè)品質(zhì)網(wǎng)站。

這篇文章主要講解了“ASP.NET Core 怎么實(shí)現(xiàn)偽屬性注入”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“ASP.NET Core 怎么實(shí)現(xiàn)偽屬性注入”吧!

二.關(guān)于屬性注入

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

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

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

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

三.屬性注入解決的痛點(diǎn)

以下介紹的痛點(diǎn)是我在實(shí)際編碼過程中遇到的一些,如果還有其他的,歡迎在評(píng)論和我交流

我所遇到的痛點(diǎn),我歸納為三條:

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

2.減少或消除因構(gòu)造方法注入造成子類繼承后的 base 調(diào)用鏈。

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

第一條:

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

ASP.NET Core 怎么實(shí)現(xiàn)偽屬性注入

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

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

ASP.NET Core 怎么實(shí)現(xiàn)偽屬性注入

第二條:

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

這樣做每次都要調(diào)用 base 將依賴對(duì)象傳遞給基類,如果繼承關(guān)系有多層,將會(huì)造成更大的影響。

ASP.NET Core 怎么實(shí)現(xiàn)偽屬性注入

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

四. 偽屬性注入核心思想

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

五. 為 Controller 實(shí)現(xiàn)偽屬性注入

Controller 的實(shí)現(xiàn)較為特殊,Controller 默認(rèn)是不會(huì)通過自帶容器來 Resolve&Activate 的,是通過MVC自身管理的,但是微軟提供了這樣的方法:

services.AddControllers().AddControllersAsServices();

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

ASP.NET Core 怎么實(shí)現(xiàn)偽屬性注入

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

定義 Controller 基類

ASP.NET Core 怎么實(shí)現(xiàn)偽屬性注入

Controller 繼承基類

ASP.NET Core 怎么實(shí)現(xiàn)偽屬性注入

改造 Controller 激活器

ASP.NET Core 怎么實(shí)現(xiàn)偽屬性注入

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

替換默認(rèn) Controller 激活器

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

運(yùn)行測試

ASP.NET Core 怎么實(shí)現(xiàn)偽屬性注入

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

六. 為 Application Service 實(shí)現(xiàn)偽屬性注入

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

定義應(yīng)用服務(wù)基類接口

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

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

定義具體服務(wù),以 User 服務(wù)為例

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

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

定義特殊的注冊(cè)服務(wù)的方法,以便實(shí)現(xiàn) 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;
  }
  // 可以反射程序集調(diào)用此方法實(shí)現(xiàn)批量自動(dòng)注冊(cè)應(yīng)用服務(wù)
  public static IServiceCollection AddApplicationService(this IServiceCollection services, Type serviceType,Type implType)
  {
    services.AddTransient(serviceType, sp =>
    {
      //獲取服務(wù)實(shí)現(xiàn)的實(shí)例
      var implInstance = ActivatorUtilities.CreateInstance(sp, implType); ;

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

注冊(cè)測試服務(wù)

ASP.NET Core 怎么實(shí)現(xiàn)偽屬性注入

Controller 注入測試服務(wù)

ASP.NET Core 怎么實(shí)現(xiàn)偽屬性注入

運(yùn)行測試

ASP.NET Core 怎么實(shí)現(xiàn)偽屬性注入

七.結(jié)束

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

感謝各位的閱讀,以上就是“ASP.NET Core 怎么實(shí)現(xiàn)偽屬性注入”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)ASP.NET Core 怎么實(shí)現(xiàn)偽屬性注入這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司,,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

網(wǎng)站名稱:ASP.NETCore怎么實(shí)現(xiàn)偽屬性注入-創(chuàng)新互聯(lián)
文章位置:http://jinyejixie.com/article48/djschp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、搜索引擎優(yōu)化、面包屑導(dǎo)航、響應(yīng)式網(wǎng)站、靜態(tài)網(wǎng)站、云服務(wù)器

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計(jì)
铁岭市| 巴楚县| 永胜县| 方正县| 正阳县| 祁东县| 沙河市| 镇雄县| 龙山县| 东丰县| 丰宁| 庄浪县| 安岳县| 建宁县| 甘泉县| 蒙阴县| 达日县| 弥渡县| 鄂托克旗| 侯马市| 涟源市| 固安县| 贵溪市| 长寿区| 永登县| 临夏市| 隆子县| 尼木县| 盈江县| 潼关县| 子长县| 桓台县| 邹城市| 镇雄县| 临颍县| 五华县| 庆云县| 都安| 遂宁市| 鹤壁市| 安泽县|