asp.net core 3.x 模块化开发之HostingStartup
我们希望将一个项目(dll)看做一个模块/插件,一个模块往往需要在应用启动时做一些初始化工作,比如向ioc容器添加一些服务,为应用配置对象添加自己的数据源;也希望在应用关闭时做一些收尾工作,asp.net core为我们提供了这种机制,先来看看如何使用,再讲讲原理。
如何使用?
1、创建asp.net core 3.1的web应用程序,webapplication6
2、创建我们的模块/插件项目,一个standard2.1项目叫classlibrary2
3、在插件项目classlibrary2中定义实现ihostingstartup的类
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 }
5、在插件项目classlibrary2中随便找个类文件中,设置[assembly: hostingstartupattribute(typeof(classlibrary2.hostingstartup))]
6、在主程序webapplication6中设置环境变量,
除了这样配置,我们也可以在主程序的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容器注册各种服务、设置应用配置的数据源等
多个模块的启动顺序是啥?
按配置的顺序加载模块的,所以最少依赖的模块应该写在前面,这个设计不如abp
模块之间如何通讯?
办法1、直接引用,配置时最好将被依赖的模块放前面
办法2、不添加直接引用关系,而用中间层实现
如添加一个中间项目,定义各种接口,由模块b来实现,在模块b中向容器注册自己的服务。模块a引用中间类库,直接在使用地方注入接口就ok啦
应用关闭时模块如果做一些收尾工作?
可以定义一个应用生命周期事件处理程序(实现ihostedapplicationlifetime),在不同事件中定义此模块的收尾工作。然后在模块启动类中向ioc注册这个服务。但这样有个问题,默认的生命周期事件处理程序被我们替换掉了,所以我们的类应该用构造函数注入ihostedapplicationlifetime,然后再调用它一次
每次写点东西都语无伦次,哈哈