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.