我有模块化的ASP.NET Core应用程序。回到.NET Core 1.1的日子,我以AddScoped
方法构建服务(AddSingleton
,public void ConfigureServices(IServiceCollection services)
...),如下所示:
public void ConfigureServices(IServiceCollection services)
{
//...
var sp = services.BuildServiceProvider();
GlobalConfiguration.ModuleInitializers = sp.GetServices<IModuleInitializer>();
foreach (var moduleInitializer in GlobalConfiguration.ModuleInitializers)
moduleInitializer.ConfigureServices(services, this.Configuration, this.Environment);
}
每个模块(库)都有自己的类,该类实现“ IModuleInitializer”并注册服务:
public class ModuleInitializer : IModuleInitializer
{
public void ConfigureServices(IServiceCollection serviceCollection, IConfiguration configuration, IHostingEnvironment environment)
{
serviceCollection.AddScoped<....>();
serviceCollection.AddScoped<...>();
...
从.NET Core 2.2迁移到3.1时,我收到警告:
从应用程序代码中调用“ BuildServiceProvider”会导致 正在创建的单例服务的其他副本。考虑 诸如依赖项注入服务之类的替代方案 '配置'
我已经接受了自我教育,这意味着什么,问题出在哪里……,但是我在如何在模块设计应用程序中正确配置服务方面遇到了问题。
我还需要从Internet获得有关模块的信息。我的问题是这种方法是否有效,还是有更好的建议?
public Startup(IConfiguration configuration)
{
Configuration = configuration; //From https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup?view=aspnetcore-3.1
}
public void ConfigureServices(IServiceCollection services)
{
...
var serverSett = this.Configuration.GetSection("Server").Get<ServerSettings>();
string[] allowedModules;
using (var httpClientHandler = new HttpClientHandler())
{
allowedModules = //Get allowed modules from web
}
if (allowedModules.Any(t => t == "Shopping");
services.AddShopping(); //Extension method in Shopping library which register own services.
if (allowedModules.Any(t => t == "Offer");
services.AddOffer(); //Extension method in Offer library which register own services.
}
答案 0 :(得分:0)
使用DI设置DI有点问题,而且肯定有问题。
为什么不仅仅使用一些反射来获取IModuleInitializers。
var moduleInitializers = typeof(MyAssembly).GetTypeInfo().Assembly
.GetTypes()
.Where(type =>
!type.GetTypeInfo().IsAbstract &&
typeof(IModuleInitializer).IsAssignableFrom(type))
.Select(type => Activator.CreateInstance(type))
.Cast<IModuleInitializer>()
.ToArray();
foreach (var moduleInitializer in moduleInitializers)
moduleInitializer.ConfigureServices(services, this.Configuration, this.Environment);
关于第二个问题,我无法给您建议。但是我会质疑是否需要动态设置应用程序,除非您真的很需要。