Use dependency injection in static class

31,917

You basically have two options:

  1. Change the class from static to an instance class and supply the dependency through Constructor Injection.
  2. Supply the dependency to the class's public method through Method Injection.

Here are examples for each option.

Option 1. Change the class from static to an instance class

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;
    }
}

2. Supply the 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;
    }
}

Less favorable options

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.

Share:
31,917

Related videos on Youtube

Kamousagi
Author by

Kamousagi

Adoro los legos, rompecabezas muy grandes, desarrollo de software, juegos de pc, acuarelas, moras, Tacna Sour (solo en Tacna-Peru), gatos tricolor, las plantas y arboles frutales. Me gusta iniciar nuevas amistades y tocar temas variados. Siempre hay momento para una cerveza con los amigos. Dispuesto a ayudar a quien se pueda.

Updated on April 22, 2022

Comments

  • Kamousagi
    Kamousagi about 2 years

    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;
        }
    }
    
    • Chetan
      Chetan about 5 years
      You want to inject IConfiguration ? Why not non-static class?
    • Kamousagi
      Kamousagi about 5 years
      Yes, I need inject IConfiguration, if I do not find a solution I will have to use no-static class
    • TheGeneral
      TheGeneral about 5 years
      If you could do this, this would be weird and it would likely need to be refactored later. You static class has no right to ask for a dependency, it defeats the point of being static and the main spirit of DI
    • Ali Zahid
      Ali Zahid about 5 years
      You also have the option of using method injection public static TResponse Execute(string metodo, TRequest request, IConfiguration conf)
  • Anastasios Moraitis
    Anastasios Moraitis almost 5 years
    @Steven When the 1st option is implemented, do we also need to add this class a service?
  • André Reichelt
    André Reichelt about 4 years
    @Steven In a web api environment with your second scenario, where do I get the config from in my controller method?
  • Steven
    Steven about 4 years
    You inject it through the controller's constructor.
  • sridawg
    sridawg over 3 years
    You can also create a static property and a public static method in your static class and set the configuration property there instead of passing it in your methods, makes it a little cleaner imo.
  • Steven
    Steven over 3 years
    @sridawg what you are describing is called Ambient Context and it's an anti-pattern.
  • Tommix
    Tommix over 2 years
    sadly none of this useful in many scenarios.
  • Steven
    Steven over 2 years
    @Tommix, if my answer doesn't fit your scenario, you might want to raise a new question here at SO.