Home > Software engineering >  C# Dependency Injection In Constructor with a parameter at runtime
C# Dependency Injection In Constructor with a parameter at runtime

Time:11-03

Perhaps I am missing something or tried something improperly, but I thought I would reach out.

I have a singleton service that I want to create multiple times. The service has the same logic except for a configuration parameter. So I want to inject a parameter at runtime into the service constructor.

Is this possible, or will I have to do something more elaborate?

Thanks for your input.

For example…


// I am creating three different configurations

    services.Configure<ProfileCacheOptions>(
        ProfileCacheOptions.Key1,
        config.GetSection(ProfileCacheOptions.Key1));

    services.Configure<ProfileCacheOptions>(
        ProfileCacheOptions.Key2,
        config.GetSection(ProfileCacheOptions.Key2));

    services.Configure<ProfileCacheOptions>(
            ProfileCacheOptions.Key2,
            config.GetSection(ProfileCacheOptions.Key3));


        .
        .
        .


    // I have tried multiple ways to inject a parameter, but as you can see
    // my last attempt was a simple string representing the key
    services.AddSingleton<ICachedDataSource<Class1>,
        MemoryCacheData<Class1>>(ProfileCacheOptions.Key1);

    services.AddSingleton<ICachedDataSource<Class2>,
        MemoryCacheData<Class2>>(ProfileCacheOptions.Key2);

    services.AddSingleton<ICachedDataSource<Class3>,
        MemoryCacheData<Class3>>(ProfileCacheOptions.Key3);

    // The proposed argument, whatever it may be
    public MemoryCacheData(
        IMemoryCache cache,
        IOptionsSnapshot<CachedDataBaseClassOptions> options,
        string TheArgument

    {
        _options = options.Get(TheArgument);
    }


I have tried creating an argument class and multiple attempts to create a runtime injected parameter.

CodePudding user response:

You can create an instance of the singleton before you add it to the DI container, like so:

var singleton1 = new MemoryCacheData<Class1>(ProfileCacheOptions.Key1);
services.AddSingleton(typeof(ICachedDataSource<Class1>), singleton1);

CodePudding user response:

You have to provide a factory (or in this case a simple Func<>) that creates the desired instance at runtime. Something like this:

services.AddSingleton<ICachedDataSource<Class1>>(provider =>
{
    // The provider is the running DI container and you can ask
    // for any service as usual to retrieve dependencies
    var cacheOptions = provider.GetRequiredService<ICachedDataSource<Class1>>();
    var data = new MemoryCacheData<Class1>(cacheOptions);

    return data;
});

I think it doesn't fully match your code, but hopefully you understand the approach and can use it.

  • Related