'Use dependency injection in static class

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


Solution 1:[1]

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 they are all less favorable, because they would either cause code smells or anti-patterns.

For instance, you might be inclined to use a Service Locator, which is an anti-pattern. Ambient Context; same thing. Property Injection, on the other hand, causes Temporal Coupling, which is a code smell.

Solution 2:[2]

i had this problem and i developed this nuget package: ServiceCollectionAccessorService

repo: ServiceCollectionAccessorService it is basically a static class that holds access to root service collection which you can build your provider from it:

private static LogData GetLogData() => ServiceCollectionAccessor.Services.BuildServiceProvider().GetRequiredService<LogData>();

this package is operational in my work and we did not have any problem. I had no problem resolving scoped services as well. I hope this could help anyone with the same problem.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Hadi Bazmi