c# - 是否可以在运行时扩展 IServiceProvider

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

TLDR:是否可以在 Startup 运行后修改 IServiceProvider

我在运行时运行 dll(它实现了我的接口(interface))。因此有一个文件监听器后台作业,它会等到 plugin-dll 被删除。现在我想将这个 dll 的类注册到依赖注入(inject)系统。因此,我将 IServiceCollection 作为 Singleton 添加到 ConfigureServices 中的 DI 以在另一个方法中使用。

因此我创建了一个测试项目并尝试修改 Controller 中的 ServiceCollection,因为这比剥离后台作业更容易。

services.AddSingleton<IServiceCollection>(services);

所以我将 IServiceCollection 添加到我的 Controller ,以检查在 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,即使在多次调用后服务计数每次都会增加,但我不知道'通过 IServiceProvider 获取引用。

现在我的问题是:这是否可能实现,是的,如何实现。或者我不应该这样做?

最佳答案

Is it possible to modify the IServiceProvider after the Startup has ran?

简短回答:

一旦 IServiceCollection.BuildServiceProvider() 被调用,对集合的任何更改都不会影响构建的提供者。

使用工厂委托(delegate)来延迟外部实现的加载,但这必须像注册的其余部分一样在启动时完成。

services.AddSingleton<IMyInterface>(_ => {
    //check if dll exist and load it
    //....
    var implementation = new ForeignClassFromExternalDll();
    return implementation;
});

您现在可以显式地将您的接口(interface)注入(inject)到 Controller 构造函数中

private readonly IMyInterface myInterface;

public MyController(IMyInterface myInterface) {
    this.myInterface = myInterface;
}

[HttpGet]
public IActionResult MyAction() {
    return Json(myInterface.DoSomething());
}

并且在解析 Controller 时解析该接口(interface)时将调用加载 dll 逻辑。

关于c# - 是否可以在运行时扩展 IServiceProvider,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56057871/

相关文章:

c# - IOS 上的 Bouncy CaSTLe ECDSA 签名/验证行为不一致

c# - TransactionScope 性能问题

c# - MVC ASP.NET 正在使用大量内存

c# - 如何将依赖项注入(inject)扩展方法?

php - laravel - 依赖注入(inject)和 IoC 容器

c# - 使用存储访问框架在 Google Drive 上存储文件

c# - 如何将作用域服务注入(inject) DbContext?网络核心

c# - 应该在 DTO 模型中还是在目标实体模型中执行计算?

c# - asp.net core文件上传始终为空

scala - 当我使用 "Reader monad"进行依赖注入(inject)时如何注入(inject)多个依赖项?