当我为 ASP.NET Core 应用程序创建 webhost 时,我可以指定 Startup
类而不是实例。
您自己的 Startup 类的构造函数可以采用通过 DI 提供的参数。我知道如何在 ConfigureServices
中为 DI 注册服务,但由于它是该类的成员,所以这些服务不适用于我的启动类的构造函数。
如何注册可用作 Startup 类的构造函数参数的服务?
原因是我必须提供一个对象实例,该实例必须在创建虚拟主机之前/之外创建,并且我不想以类似全局的方式传递它。
创建 IWebHost 的代码:
this.host = new WebHostBuilder()
.UseConfiguration(config)
.UseKestrel()
.UseIISIntegration()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<WebStartup>()
log.Debug("Run webhost");
this.host.Start();
WebStartup
的构造函数:
public WebStartup(IHostingEnvironment env, MyClass myClass)
{
var config = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddEnvironmentVariables()
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
.Build();
...
}
具体来说,我如何在这个例子中注册 MyClass
(这显然必须在 WebStartup
被 IWebHost
实例化之前完成)?
最佳答案
虽然 Steven 的担忧是有道理的并且您应该注意它们,但从技术上讲,配置用于解析 Startup 类的 DI 容器是可行的。
ASP.NET 托管使用依赖项注入(inject)来连接 Startup 类的一个实例,并让我们使用 ConfigureServices
将我们自己的服务添加到该容器中。 IWebHostBuilder
上的扩展方法:
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.ConfigureServices(services => services.AddSingleton<IMyService, MyService>())
.UseStartup<Startup>()
.Build();
host.Run();
和:
public Startup(IMyService myService)
{
myService.Test();
}
事实上,所有UseStartup<WebStartup>
确实是将其添加为 IStartup
的服务实现到托管 DI 容器 ( see this )。
请注意,您的服务实例将在应用程序 容器中再次解析为IServiceProvider
的新实例。将建成。但是,服务的注册将传递给应用程序 IServiceCollection
在你的启动类中。
关于c# - 如何配置 Startup 类构造函数可用的 DI 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40221611/