I need to use Dependency Injection in a static class.
the method in the static class needs the value of an injected dependency.
The following code sample demonstrates my problem:
public static class XHelper
{
public static TResponse Execute(string metodo, TRequest request)
{
// How do I retrieve the IConfiguracion dependency here?
IConfiguracion x = ...;
// The dependency gives access to the value I need
string y = x.apiUrl;
return xxx;
}
}
You can use dependency injection in a static class using method or property injection. However, you cannot use constructor injection in a static class because the constructor of a static class cannot accept any parameters.
Both Constructor Injection and Property Injection are applied inside the startup path of the application (a.k.a. the Composition Root) and require the consumer to store the dependency in a private field for later reuse. This requires the constructor and property to be instance members, i.e. non-static.
While a static class allows only static methods and and you cannot pass static class as parameter. A Singleton can implement interfaces, inherit from other classes and allow inheritance. While a static class cannot inherit their instance members. So Singleton is more flexible than static classes and can maintain state.
Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor. However, they can contain a static constructor.
You basically have two options:
static
to an instance class and supply the dependency through Constructor Injection.Here are examples for each option.
Change the class from static
to an instance class and supply IConfiguracion
through Constructor Injection. XHelper
should in that case be injected into the constructor of its consumers. Example:
public class XHelper
{
private readonly IConfiguration config;
public XHelper(IConfiguration config)
{
this.config = config ?? throw new ArgumentNullException("config");
}
public TResponse Execute(string metodo, TRequest request)
{
string y = this.config.apiUrl;
return xxx;
}
}
IConfiguration
to the Execute
method through Method Injection.Example:
public static class XHelper
{
public static TResponse Execute(
string metodo, TRequest request, IConfiguration config)
{
if (config is null) throw new ArgumentNullException("config");
string y = config.apiUrl;
return xxx;
}
}
There are of course more options to consider, but I consider them all to be less favorable, because they would either cause code smells or anti-patterns.
For instance, you might be inclined to use a Service Locator, but this is an anti-pattern. Ambient Context; same thing. Property Injection, on the other hand, causes Temporal Coupling, which is a code smell.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With