Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Register Service at Runtime via DI?

I am using ASP.NET Core and want to add a service to the IServiceProvider at runtime, so it can be used across the application via DI.

For instance, a simple example would be that the user goes to the settings controller and changes an authentication setting from "On" to "Off". In that instance I would like to replace the service that was registered at runtime.

Psuedo Code in the Settings 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>());
}

This logic works fine when I am doing it in my Startup.cs because the IServiceCollection has not been built into a IServiceProvider. However, I want to be able to do this after the Startup has already executed. Does anyone know if this is even possible?

like image 206
A.Fry Avatar asked Nov 17 '16 12:11

A.Fry


1 Answers

Instead of registering/removing service at runtime, i would create a service factory which decides right service at runtime.

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

Usage in a class:

public class SomeClass
{
    public SomeClass(IAuthenticationServiceFactory _authenticationServiceFactory)
    {
        var authenticationService = _authenticationServiceFactory.GetAuthenticationService();
    }
}
like image 113
adem caglin Avatar answered Sep 21 '22 07:09

adem caglin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!