理解ASP.NET Core 依賴注入

目錄:web

1、什麼是依賴注入cookie

1.一、什麼是依賴?app

1.二、 什麼是注入?async

1.三、依賴注入解決的問題ide

2、服務的生命週期(.Net Core DI)模塊化

3、替換默認服務容器單元測試

  3.一、爲何替換默認服務容器?學習

  3.二、如何替換服務容器測試


 

1、什麼是依賴注入ui

一、 什麼是依賴

Rely類

  public class Rely
    {
        public Task Test(string testMessage)
        {
            Console.WriteLine(testMessage);
            return Task.FromResult(0);
        }
  }

 

Output類

public class Output
    {
        Rely rely = new Rely();
        public async Task Out()
        {
            await rely.Test("這是一個測試消息");
        }
    }

Output類須要Rely類來幫助它實現輸出的功能,這樣Output類對Rely類產生了依賴,能夠理解爲Output依賴於Rely

依賴的一個設計原則:依賴於抽象,而不是具體的實現,這個後面會具體解釋的

 

二、 什麼是注入

修改Output類

public class Output
    {
        private Rely _rely;
        public Output(Rely rely)
        {
            _rely = rely;
        }
        public async Task Out()
        {
            await _rely.Test("這是一個測試消息");
        }
    }

在這裏Output類不去實例化Rely類,而是經過其餘人傳遞給我,我只用就好。到底怎麼理解注入呢?

簡單來講就是別人對依賴建立實例化,我本身只負責使用,別人建立好了給我使用,這麼一個過程能夠理解爲注入

這裏主要體現了控制反轉 (IoC)的思想,什麼是IOC ?咱們看看下面的圖就好理解了

 

 

 

直接依賴關係在運行的時候A調用B,B調用C,編譯的時候A取決於B,B取決於C。

而在反轉依賴關係中, A能夠調用B實現的抽象上的方法,讓A能夠在運行時調用B,而B又在編譯時依賴於A控制的接口,程序運行時流程跟直接依賴關係同樣。可是插入了接口意味着能夠輕鬆的有不一樣實現

 

三、 依賴注入解決的問題

依賴注入主要體現了IOC思想,IOC將實現詳細信息編寫爲依賴而且實現了更高級的抽象,所以程序測試性,維護性,模塊化程度都更高了。這也就對應了剛剛的那個設計規則--依賴於抽象,而不是具體的實現。

那麼依賴注入到底解決了哪些問題呢?

問題一:在直接依賴關係中若是A類須要更換爲其餘實現,那麼就必須得修改B類

問題二:若是有多個依賴B類的類,那麼將會實例化多個配置,這樣代碼會比較分散和冗餘

問題三:這種實現方法很難實現單元測試

解決這些問題的辦法:

一:使用了接口抽象話依賴關係的實現,改動實現只須要改動注入的地方便可

二:註冊服務容器中的依賴關係,有多處須要不準多出實例化配置,直接在Startup.ConfigureServices中註冊便可

 

2、服務的生命週期(.Net Core DI)

在.NET Core中DI的核心分爲兩個組件:IServiceCollection和 IServiceProvider。

    •   IServiceCollection---負責註冊
    •   IServiceProvider---負責提供實例

 

Startup.csConfigureServices中註冊服務

   public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

 
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();//單例生存期

            services.AddScoped<IHttpContextAccessor, HttpContextAccessor>();//範圍生存期

            services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();//暫時生存期

 
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

 

一、 Transient暫時生存期)--暫時生存期服務是每次從服務容器進行請求時建立的。 這種生存期適合輕量級、 無狀態的服務。

暫時生存期會在每次請求的時候建立一個實例

二、 Scoped範圍生存期)--範圍生存期服務是每一個客戶端鏈接時建立的一次實例

範圍生存期會在客戶端鏈接時建立一次實例,而後每次請求的實例都是相同的

三、 Singleton單例生存期)--單例生存期會在程序第一次請求是建立一次實例

單例生存期僅會在第一次鏈接時建立一次實例,全部整個程序使用的實例都是同一個實例

 

3、替換默認服務容器

一、 爲何替換默認服務容器

咱們能夠首先理解下什麼是服務容器—依賴注入把依賴的建立給了別人,別人建立好了再給咱們使用。那麼在哪裏建立依賴呢?或者說在那裏管理依賴呢?這裏就有了容器這個概念,負責管理系統中全部的依賴。

那麼咱們爲何要替換容器呢?

內置的服務容器足夠實現一些小型的項目或知足大多數的消費者,可是遇到大型的項目就比較麻煩了,依賴較多,內置的服務容器就顯得有點短板了。當咱們遇到這些問題的時候就能夠考慮替換默認服務容器。

二、 如何替換服務容器

這裏咱們說下替換服務容器爲Autofac

安裝適當的包

    •   Autofac
    •   Autofac.Extensions.DependencyInjection

在 Startup.ConfigureServices 中配置返回 爲IServiceProvider:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    // Add other framework services
    // Add Autofac
    var containerBuilder = new ContainerBuilder();
    containerBuilder.RegisterModule<DefaultModule>();
    containerBuilder.Populate(services);
    var container = containerBuilder.Build();
    return new AutofacServiceProvider(container);

}

 

若是要使用第三方容器的話, Startup.ConfigureServices 必須返回 IServiceProvider。

而後咱們在 DefaultModule 中配置 Autofac

public class DefaultModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<CharacterRepository>().As<ICharacterRepository>();
    }
}

 

 

 


 

  歡迎你們掃描下方二維碼,和我一塊兒學習更多的知識😊

 

  

相關文章
相關標籤/搜索