carbonero1891
carbonero1891

Reputation: 35

Dependency injection in my singleton class .NET Core

I'm having trouble injecting the dependency I pass into the constructor of my Asegurador class.

When I want to instantiate, _instance = new Asegurador(); I don't have the parameter required by the constructor (IGeneralRepository), how can I solve this problem?

Note that my Asegurador class is a singleton.

private Asegurador(IGeneralRepository generalRepository)
    {
        _token = GetTokenAsync().Result;
        _repository = generalRepository;
    }
    public static Asegurador Instance
    {
        get
        {
            if (_instance == null)
            {
                _local = System.Environment.GetEnvironmentVariable("SEGUROS_LOCAL") ?? "local";
                _instance = new Asegurador();
            }
            return _instance;
        }
    }

Upvotes: 1

Views: 3813

Answers (1)

ddfra
ddfra

Reputation: 2565

When using a DI container you can (and should) let it take care of handling the Lifetime of a dependency.

.Net core's dependency injection lets you define 3 different lifetimes for your services (Docs):

  • Transient: a transient service is recreated each time it is injected
  • Scoped: a scoped service is created once for each request
  • Singleton: a singleton is created once in the whole application lifetime.

The best approach to achieve what you are trying to do is the following:

  • Amend your Asegurador class so that it has a public constructor and get rid of the static Instance property

    public class Asegurador {
        public Asegurador(IGeneralRepository generalRepository)
        {
           _token = GetTokenAsync().Result; //I know too few about it but I would try to pass it as a dependency as well
           _repository = generalRepository;
        }
    }
    
  • instead of calling Asegurador.Instance inject the dependency in the client class

     public class IUseTheAsegurador {
         private Asegurador _asegurador;
         public IUseTheAsegurador(Asegurador asegurador)
         {
           _asegurador = asegurador;
         }
     }
    
  • Register all in the DI in your Startup.cs:

     public void ConfigureServices(IServiceCollection services)
     {
        ...
        services.AddSingleton<Asegurador>();
        services.AddScoped<IUseAsegurador>(); //This can be Singleton or Transient as well, depending on your needs
        ...
     }
    

I (a lot of people actually :D) prefer this approach because it leaves the responsability of guaranteeing a single instance to the DI and also because lets you write unit tests for the client class (IUseTheAsegurador in the example) in an easier way.

Upvotes: 2

Related Questions