通过DI在运行时注册服务?

A.F*_*Fry 4 c# asp.net-core-mvc .net-core asp.net-core

我正在使用ASP.NET Core并希望在运行时向IServiceProvider添加服务,因此可以通过DI在整个应用程序中使用它.

例如,一个简单的例子是用户进入设置控制器并将认证设置从"开"更改为"关".在那个例子中,我想替换在运行时注册的服务.

设置控制器中的Psuedo代码:

if(settings.Authentication == false)
{
     services.Remove(ServiceDescriptor.Transient<IAuthenticationService, AuthenticationService>());
     services.Add(ServiceDescriptor.Transient<IAuthenticationService, NoAuthService>());
}
else
{
     services.Remove(ServiceDescriptor.Transient<IAuthenticationService, NoAuthService>
     services.Add(ServiceDescriptor.Transient<IAuthenticationService, AuthenticationService>());
}
Run Code Online (Sandbox Code Playgroud)

当我在Startup.cs中执行此操作时,此逻辑工作正常,因为IServiceCollection尚未构建到IServiceProvider中.但是,我希望能够在启动已经执行之后执行此操作.有谁知道这是否可能?

ade*_*lin 8

我不是在运行时注册/删除服务,而是创建一个服务工厂,它在运行时决定正确的服务.

services.AddTransient<AuthenticationService>();
services.AddTransient<NoAuthService>();
services.AddTransient<IAuthenticationServiceFactory, AuthenticationServiceFactory>();
Run Code Online (Sandbox Code Playgroud)

AuthenticationServiceFactory.cs

public class AuthenticationServiceFactory: IAuthenticationServiceFactory
{
     private readonly AuthenticationService _authenticationService;
     private readonly NoAuthService_noAuthService;
     public AuthenticationServiceFactory(AuthenticationService authenticationService, NoAuthService noAuthService)
     {
         _noAuthService = noAuthService;
         _authenticationService = authenticationService;
     }
     public IAuthenticationService GetAuthenticationService()
     {
          if(settings.Authentication == false)
          {
             return _noAuthService;
          }
          else
          {
              return _authenticationService;
          }
     }
}
Run Code Online (Sandbox Code Playgroud)

在课堂上使用:

public class SomeClass
{
    public SomeClass(IAuthenticationServiceFactory _authenticationServiceFactory)
    {
        var authenticationService = _authenticationServiceFactory.GetAuthenticationService();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,但我不认为这对我有用。我让我的例子非常简单来说明这个概念,但这不是我的*实际*问题。我有一个模块化系统,可以在运行时“安装”插件,并且这些插件具有需要添加到 ServiceCollection 的服务。我的问题是我没有找到一种令人满意的在运行时添加这些服务的方法。感谢您抽出时间回复! (7认同)
  • @Dawid你有什么权威说这是"正确的方法"?你是说_"我也会这样做"_?为什么?为什么这是一个很好的答案? (3认同)
  • @CodeCaster:引导后也不应该更改“ServiceCollection”。当 ASP.NET Core 调用“services.BuildServiceProvder()”(在“ConfigureServices”之后和“Configure”调用之前的某个位置)时,会构建提供程序,对“IServiceCollection”发生的更改并不重要,并且再次调用“.BuildServiceProvder” ()` 只是创建一个新的提供程序,旧的提供程序仍然在更改之前发生的单例服务中引用 (2认同)