是否可以在运行时扩展IServiceProvider

时间:2019-05-09 10:57:09

标签: c# asp.net-core dependency-injection

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}}。

现在我的问题是:那有可能实现,是的。还是我不应该这样做?

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逻辑。