TLDR:是否可以在启动运行后修改IServiceProvider
?
我在运行时正在运行dll(实现了我的界面)。因此,有一个文件侦听器后台作业,它会等到plugin-dll被删除。现在,我想将这个dll的类注册到依赖项注入系统。因此,我在IServiceCollection
内的DI中添加了ConfigureServices
作为Singleton以便在另一种方法内使用。
因此,我创建了一个测试项目,只是试图在控制器中修改ServiceCollection
,因为它比剥离后台作业更容易。
services.AddSingleton<IServiceCollection>(services);
因此,我将IServiceCollection
添加到了控制器中,以检查是否可以在运行Startup
类之后将类添加到DI中。
[Route("api/v1/test")]
public class TestController : Microsoft.AspNetCore.Mvc.Controller
{
private readonly IServiceCollection _services;
public TestController(IServiceCollection services)
{
_services = services;
var myInterface = HttpContext.RequestServices.GetService<IMyInterface>();
if (myInterface == null)
{
//check if dll exist and load it
//....
var implementation = new ForeignClassFromExternalDll();
_services.AddSingleton<IMyInterface>(implementation);
}
}
[HttpGet]
public IActionResult Test()
{
var myInterface = HttpContext.RequestServices.GetService<IMyInterface>();
return Json(myInterface.DoSomething());
}
}
public interface IMyInterface { /* ... */ }
public class ForeignClassFromExternalDll : IMyInterface { /* ... */ }
已成功将服务添加到IServiceCollection
,但是即使多次调用后,更改仍未持久化到HttpContext.RequestServices
,但每次服务计数都增加了,但是{ {1}}。
现在我的问题是:那有可能实现,是的。还是我不应该这样做?
答案 0 :(得分:2)
在启动运行后是否可以修改IServiceProvider?
简短答案:否。
一旦调用IServiceCollection.BuildServiceProvider()
,对集合的任何更改都不会对生成的提供程序产生影响。
使用工厂委托来推迟外部实现的加载,但这必须像其余注册一样在启动时完成。
services.AddSingleton<IMyInterface>(_ => {
//check if dll exist and load it
//....
var implementation = new ForeignClassFromExternalDll();
return implementation;
});
您现在可以将接口显式注入到控制器构造函数中
private readonly IMyInterface myInterface;
public MyController(IMyInterface myInterface) {
this.myInterface = myInterface;
}
[HttpGet]
public IActionResult MyAction() {
return Json(myInterface.DoSomething());
}
,当解析控制器时,在解析该接口时,将调用load dll逻辑。