咱们但愿将一个项目(dll)看作一个模块/插件,一个模块每每须要在应用启动时作一些初始化工做,好比向IOC容器添加一些服务,为应用配置对象添加本身的数据源;也但愿在应用关闭时作一些收尾工做,asp.net core为咱们提供了这种机制,先来看看如何使用,再讲讲原理。web
一、建立asp.net core 3.1的web应用程序,WebApplication6asp.net
二、建立咱们的模块/插件项目,一个Standard2.1项目叫ClassLibrary2函数
三、在插件项目ClassLibrary2中定义实现IHostingStartup的类ui
1 public class HostingStartup : IHostingStartup 2 { 3 public void Configure(IWebHostBuilder builder) 4 { 5 //向IOC容器添加或替换各类服务 6 builder.ConfigureServices((c,b)=> { 7 b.AddSingleton<Class1>(); 8 }); 9 //为应用配置对象添加更多数据源 10 builder.ConfigureAppConfiguration(c => { 11 c.AddInMemoryCollection(new Dictionary<string, string> { {"a","tttt" } }); 12 });
//处理当前模块的其它初始化操做 13 } 14 }
五、在插件项目ClassLibrary2中随便找个类文件中,设置[assembly: HostingStartupAttribute(typeof(ClassLibrary2.HostingStartup))]spa
六、在主程序WebApplication6中设置环境变量,.net
除了这样配置,咱们也能够在主程序的Program.main配置主机时手动覆盖配置值,以达到设置插件关联的程序集的目的,多个插件程序集用分号“;”分割插件
1 public static IHostBuilder CreateHostBuilder(string[] args) => 2 Host.CreateDefaultBuilder(args) 3 .ConfigureWebHostDefaults(webBuilder =>{ 4 webBuilder.UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "ClassLibrary2"); 5 webBuilder.UseStartup<Startup>(); 6 });
还可使用webBuilder.UseSetting(WebHostDefaults.HostingStartupExcludeAssembliesKey, "ClassLibrary3");排出一些程序集,不把这些程序集当作插件来加载设计
程序启动时会根据环境变量找到对应的插件程序集
根据程序集找到关联的 HostingStartupAttribute
经过 HostingStartupAttribute拿到插件启动类并调用其Confiure方法
方法内部能够作此插件的初始化工做、向主机IOC容器注册各类服务、设置应用配置的数据源等code
按配置的顺序加载模块的,因此最少依赖的模块应该写在前面,这个设计不如abp对象
办法一、直接引用,配置时最好将被依赖的模块放前面
办法二、不添加直接引用关系,而用中间层实现
如添加一个中间项目,定义各类接口,由模块B来实现,在模块B中向容器注册本身的服务。模块A引用中间类库,直接在使用地方注入接口就ok啦
能够定义一个应用生命周期事件处理程序(实现IHostedApplicationLifetime),在不一样事件中定义此模块的收尾工做。而后在模块启动类中向IOC注册这个服务。但这样有个问题,默认的生命周期事件处理程序被咱们替换掉了,因此咱们的类应该用构造函数注入IHostedApplicationLifetime,而后再调用它一次
每次写点东西都语无伦次,哈哈