Asp.Net Core 3.0的依賴注入改變


Asp.Net Core 3.0出來很久了,預覽版的時候就被我偶像Lemon大人,帶着嘗試摸索了一下這個

那么Asp.Net Core 3.0和Asp.Net Core 2.X到底有哪些區別呢?

Asp.Net Core 2.X是如何替換依賴注入容器的

三方替換DI容器是在Startup類的ConfigureServices方法上修改

        public void ConfigureServices(IServiceCollection services)
        {
           //...
        }

改為

        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            //...
        }

三方修改DI是編寫IServiceCollection類型的擴展方法,然后把返回值從void改為IServiceProvider


 

Asp.Net Core 3.0是如何替換依賴注入容器的

默認的Program改為了

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }

是不是有點變化?2.X以及以下都是WebHost.CreateDefaultBuilder,這里改成了Host.CreateDefaultBuilder

且Startup.ConfigureServices改為了返回值只能void了,那我們怎么修改DI容器呢?

Host有個替換DI容器的方法UseServiceProviderFactory

 

我們跟進去定義看看這個是什么

 

要實現一個IServiceProviderFactory的泛型接口~

我們跟蹤以下這個接口的定義

 

先是通過IServiceCollection轉換成一個泛型對象,再通過泛型對象轉換成IServiceProvider對象了

實驗一下

    public class DIBuilder
    {
        private string Name { get; }
        private IServiceCollection Services { get; }


        public DIBuilder(string name,IServiceCollection services)
        {
            Name = name;
            Services = services;
        }

        public IServiceProvider BuilderServiceProvider()
        {
            return Services.BuildServiceProvider();
        }
    }

因為IServiceProviderFactory要先把IServiceCollection傳入,然后轉換成容器,所以我們的DI容器得儲存這些,才能最后從DI容器轉換到IServiceProvider

我們編寫一個類繼承IServiceProviderFactory

    public class DIServiceProviderFactory : IServiceProviderFactory<DIBuilder>
    {
        public DIBuilder CreateBuilder(IServiceCollection services)
        {
            return new DIBuilder("NCoreCoder", services);
        }

        public IServiceProvider CreateServiceProvider(DIBuilder containerBuilder)
        {
Console.WriteLine($"{containerBuilder.Name}");
return containerBuilder.BuilderServiceProvider(); } }

最后返回IServiceProvider的時候,輸出一個DIBuilder.Name

調用一下DIServiceProviderFactory

 

正常輸出了

 

我們加一下輸出信息,看看整體的DI流程

 

再運行看看

 


那么網上盛傳的Startup.ConfigureContainer(T container)是怎么回事呢?

這里其實是配置我們自定義容器的東西的,比如有一些定制化DI的操作,那么就是這里面了

增加一個方法,測試一下

        public void ConfigureContainer(DIBuilder builder)
        {
            Console.WriteLine($"Startup.ConfigreContainer Name:{builder.Name}");
        }

運行再看看流程

 Startup.ConfigureServices->ServiceProviderFactory.CreateBuilder->Startup.ConfigureContainer(可忽略)->ServiceProviderFactory.CreateServiceProvider->Startup.Configure


打個廣告 如果對於這篇文章有什么要交流的,歡迎加Q群 386092459


免責聲明!

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



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