I am working with c# and .NET Core 3.1, and I have a class that looks like this.
public class MyClass : IMyClass
{
public MyClass()
{
…
}
public MyClass(IDependency dependency)
{
…
}
public MyClass(string appSettings)
{
…
}
…
}
So I know that with Dependency Injection, you can add services like this:
services
.AddScoped<IDependency, Dependency>()
.AddScoped<IMyClass, MyClass>();
and the Service Provider has rules (See https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection#multiple-constructor-discovery-rules) to select the constructor based on which has the most arguments registered (In this case, MyClass(IDependency dependency)
).
I have a specific case though, where, if a setting is found in configuration and valid, I want to use the third constructor. I planned to do that with something like this
services
.AddScoped<IDependency, Dependency>()
.AddScoped<IMyClass>(s =>
{
if(<insert config read and validation here>)
{
return new MyClass(appSetting);
}
else
{
//apply default rules to get MyClass
}
}
The problem is I can’t figure out a clean way to apply the default rules within an implementation factory. Does anyone know of a clean way to do this?
I've tried using ActivatorUtilities.CreateInstance, passing in just the ServiceProviders, but that seems to prioritize the first matching constructor, regardless of available registered dependencies (In this case MyClass()
).
I also tried using services.AddScoped<IMyClass, MyClass>();
and the implementation factory combined, calling s.GetRequiredService<IMyClass>()
in the else block, but that just results in an infinite loop of the implementation factory trying to resolve itself.