lundi 10 août 2020

Add multiple services to the IServiceCollection with a loop using reflection

During the DI container setup I have multiple services that rely on a manual setup. E.g. some of them require a database connection string. So instead of writing

services.AddTransient(typeof(TheInterface), typeof(TheImplementation));

I have to do

services.AddTransient<TheInterface>(serviceProvider => 
{
    // gather all the constructor parameters here
    return new TheImplementation(/* pass in the constructor parameters */);
});

The constructor parameters are always the same. Instead of writing this multiple times I thought about creating a collection of those services and looping through that collection. I know I can create new instances from a type by using the Activator class but I'm struggling with the conversion from a type to a generic. The following code is a sample code for demo purposes

    public void SetupServices(IServiceCollection services, string databaseConnectionString)
    {
        IDictionary<Type, Type> servicesTypes = new Dictionary<Type, Type>()
        {
            { typeof(MyInterface), typeof(MyImplementation) }
            // ... more services here
        };

        foreach (KeyValuePair<Type, Type> servicesType in servicesTypes)
        {
            services.AddTransient <??? /* servicesType.Key does not work here */> (serviceProvider =>
            {
                return Activator.CreateInstance(servicesType.Value, databaseConnectionString /*, other params */);
            });
        }
    }

The position I'm struggling is this line

services.AddTransient <??? /* servicesType.Key does not work here */>

How would I convert the service interface type to a generic one? I'm not even sure if this loop is worth the effort... but currently I have 5 services which could use it.





Aucun commentaire:

Enregistrer un commentaire