2020年3月4日 星期三

[ASP.NET Core] Dependency Injection multiple instances of interface


 ASP.NET Core   Dependency Injection  


Introduction


This article shows how to use injected services that implement the same interface.

Notice that from DOTNET 8, it supports the Keyed Services to retrieve the specified implement instance of the same interface. See Anderew Lock's article: Keyed service dependency injection container support.



Environment


ASP.NET Core 3.1.102


Implement



Assume that we implement an interface: IKeyService, by 3 classes:
·         TripleDesKeyService
·         SharedSecretService
·         RsaKeyService

And inject them like following,

public void ConfigureServices(IServiceCollection services)
{
            services.AddSingleton<IKeyServiceTripleDesKeyService>();
            services.AddSingleton<IKeyServiceSharedSecretKeyService>();
            services.AddSingleton<IKeyServiceRsaKeyService>();
}


Here are some ways to request the injected instances in other services.

Request as IEnumerable collection and resolve

private readonly TripleDesKeyService tripleDesKeyService = null;
private readonly SharedSecretKeyService sharedSecretKeyService = null;
private readonly RsaKeyService rsaKeyServicenull;

public MyService(IEnumerable<IKeyServicekeyServices)
{
    // Revolve instance
    this.tripleDesKeyService = keyServices.FirstOrDefault(x => x.GetType().Equals(typeof(TripleDesKeyService))) as TripleDesKeyService;
    this.sharedSecretKeyService = keyServices.FirstOrDefault(x => x.GetType().Equals(typeof(SharedSecretKeyService))) as SharedSecretKeyService;
    this.rsaKeyService = keyServices.FirstOrDefault(x => x.GetType().Equals(typeof(RsaKeyService))) as RsaKeyService;
}



Create a resolver delegate

public delegate IKeyService KeyServiceResolver(string className);
    
/// <summary>
/// ServiceCollectionExtensions
/// </summary>
public static class ServiceCollectionExtensions
{
        public static IServiceCollection AddCustomServices(this IServiceCollection services)
        {
            services.AddSingleton<IKeyServiceTripleDesKeyService>();
            services.AddSingleton<IKeyServiceSharedSecretKeyService>();
            services.AddSingleton<IKeyServiceRsaKeyService>();

            services.AddSingleton<KeyServiceResolver>(sp => className =>
            {
                var keyService = sp.GetServices<IKeyService>().Where(x => x.GetType().Name.Equals(className)).FirstOrDefault();
                return keyService;
            });

            return services;
        }
    }


And then request the Resolver to resolve the instances:

private readonly TripleDesKeyService tripleDesKeyService = null;
private readonly SharedSecretKeyService sharedSecretKeyService = null;
private readonly RsaKeyService rsaKeyServicenull;

public MyService(KeyServiceResolver keyServiceResolver)
{
    // Revolve instance

    this.tripleDesKeyService = keyServiceResolver(nameof(TripleDesKeyService)) as TripleDesKeyService;
    this.sharedSecretKeyService = keyServiceResolver(nameof(SharedSecretService)) as SharedSecretService;
    this.rsaKeyService = keyServiceResolver(nameof(RsaKeyService)) as RsaKeyService;
}





Reference


N/A