簡體   English   中英

通過 DI 在運行時注冊服務?

[英]Register Service at Runtime via DI?

我正在使用 ASP.NET Core 並希望在運行時向 IServiceProvider 添加服務,以便它可以通過 DI 在整個應用程序中使用。

例如,一個簡單的示例是用戶轉到設置 controller 並將身份驗證設置從“開”更改為“關”。 在那種情況下,我想替換在運行時注冊的服務。

設置中的偽代碼 Controller:

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>());
}

當我在我的 Startup.cs 中執行此邏輯時,此邏輯工作正常,因為 IServiceCollection 尚未內置到 IServiceProvider 中。 但是,我希望能夠在 Startup 已經執行之后執行此操作。 有誰知道這是否可能?

我不是在運行時注冊/刪除服務,而是創建一個服務工廠,它在運行時決定正確的服務。

services.AddTransient<AuthenticationService>();
services.AddTransient<NoAuthService>();
services.AddTransient<IAuthenticationServiceFactory, AuthenticationServiceFactory>();

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

在課堂上使用:

public class SomeClass
{
    public SomeClass(IAuthenticationServiceFactory _authenticationServiceFactory)
    {
        var authenticationService = _authenticationServiceFactory.GetAuthenticationService();
    }
}

在 Autofac 中可能有這樣的事情:

  private ILifetimeScope BeginChildScope()
  {
        return _lifetimeScope.BeginLifetimeScope(x =>
        {
            x.Register<IAuthenticationService>(b => new AuthenticationService());
        });
  }
using (var childScope = BeginChildScope())
{
   // Do sth here
}

對於 .NET Core,我認為這是唯一可能的解決方案 atm.: Best strategy for creating a child container (or isolated scope) with Microsoft.Extensions.DependencyInjection

Microsoft 在此處聲明 ASP.NET Core DI 不受支持的功能: https://learn.microsoft.com/en-us/do.net/core/extensions/dependency-injection-guidelines#default-service-container-replacement

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM