2016-11-17 93 views
2

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

例如,一個簡單的例子是用戶轉到設置控制器並將認證設置從「開啓」更改爲「關閉」。在那種情況下,我想替換在運行時註冊的服務。

的僞代碼中設置控制器:

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。但是,我希望在啓動已經執行後能夠做到這一點。有誰知道這是否可能?

回答

5

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

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

是的,這是正確的做法! –

+2

@你認爲這是「正確的方法」嗎?你的意思是_「我也會這樣做」_?爲什麼?爲什麼這是一個很好的答案? – CodeCaster

+0

因爲從設計模式的角度來看,註冊工廠隱藏了一些細節(在這種情況下獲得一些配置/設置),並提供正確的實現。 –