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