Saltar al contenido

¿Cómo registrar múltiples implementaciones de la misma interfaz en Asp.Net Core?

Esta sección fue evaluado por expertos para que tengas la garantía de la veracidad de este escrito.

Solución:

Hice una solución simple usando Func cuando me encontré en esta situación.

En primer lugar, declare un delegado compartido:

public delegate IService ServiceResolver(string key);

Entonces en tu Startup.cs, configure los múltiples registros concretos y un mapeo manual de esos tipos:

services.AddTransient();
services.AddTransient();
services.AddTransient();

services.AddTransient(serviceProvider => key =>

    switch (key)
    
        case "A":
            return serviceProvider.GetService();
        case "B":
            return serviceProvider.GetService();
        case "C":
            return serviceProvider.GetService();
        default:
            throw new KeyNotFoundException(); // or maybe return null, up to you
    
);

Y úsalo desde cualquier clase registrada con DI:

public class Consumer

    private readonly IService _aService;

    public Consumer(ServiceResolver serviceAccessor)
    
        _aService = serviceAccessor("A");
    

    public void UseServiceA()
    
        _aService.DoTheThing();
    

Tenga en cuenta que en este ejemplo el key para la resolución es un string, en aras de la simplicidad y porque OP preguntaba por este caso en particular.

Pero podría usar cualquier tipo de resolución personalizada como key, ya que generalmente no desea que un gran cambio de n-case pudra su código. Depende de cómo escale su aplicación.

Otra opción es usar el método de extensión. GetServices desde Microsoft.Extensions.DependencyInjection.

Registra tus servicios como:

services.AddSingleton();
services.AddSingleton();
services.AddSingleton();

Luego resuelve con un poco de Linq:

var services = serviceProvider.GetServices();
var serviceB = services.First(o => o.GetType() == typeof(ServiceB));

o

var serviceZ = services.First(o => o.Name.Equals("Z"));

(asumiendo que IService tiene un string propiedad llamada “Nombre”)

Asegúrate de tener using Microsoft.Extensions.DependencyInjection;

Actualizar

Fuente AspNet 2.1: GetServices

Simplemente inyecto un IEnumerable

Configurar servicios en Startup.cs

Assembly.GetEntryAssembly().GetTypesAssignableFrom().ForEach((t)=>
                
                    services.AddScoped(typeof(IService), t);
                );

Carpeta de servicios

public interface IService

    string Name  get; set; 


public class ServiceA : IService

    public string Name  get  return "A";  


public class ServiceB : IService
    
    public string Name  get  return "B";  


public class ServiceC : IService
    
    public string Name  get  return "C";  

MiControlador.cs

public class MyController

    private readonly IEnumerable _services;
    public MyController(IEnumerable services)
    
        _services = services;
    
    public void DoSomething()
    
        var service = _services.Where(s => s.Name == "A").Single();
    
...

Extensiones.cs

    public static List GetTypesAssignableFrom(this Assembly assembly)
    
        return assembly.GetTypesAssignableFrom(typeof(T));
    
    public static List GetTypesAssignableFrom(this Assembly assembly, Type compareType)
    
        List ret = new List();
        foreach (var type in assembly.DefinedTypes)
        
            if (compareType.IsAssignableFrom(type) && compareType != type)
            
                ret.Add(type);
            
        
        return ret;
    

valoraciones y reseñas

Finalizando este artículo puedes encontrar las explicaciones de otros usuarios, tú de igual manera eres capaz mostrar el tuyo si lo deseas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *