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