2016-11-17 36 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

因为从设计模式的角度来看,注册工厂隐藏了一些细节(在这种情况下获得一些配置/设置),并提供正确的实现。 –