DEV Community

Dependency Injection in NetCore

JPBlancoDB on November 09, 2019

Dependency Injection in NetCore Dependency Injection [DI] is a pattern that gives the implementation of a class to an object without nee...
Collapse
 
jcalixte profile image
Julien Calixte

Hi! Why not only use Singleton classes? What are the benefits using Scoped and Transient?

Collapse
 
jpblancodb profile image
JPBlancoDB

Hi Julien! So singleton classes only instantiate once, I would not use singleton as default because could cause you troubles. Don't think that it is going to be better for performance if you use your whole app as a singleton, on the contrary, I would recommend you if you are in doubt, just use transient as default.

One use case for singleton that I could think of right now is, for example, you have a configuration file and this does not change then you want to read it once at startup and then inject these values where is needed. Or for the service locator pattern, you could read more about this: Using a service locator.

My advice is, don't ever use singletons for classes that contain business logic.

I hope this gives you more insights into singletons!

Collapse
 
katnel20 profile image
Katie Nelson

If I have a Controller that takes a Service and that Service takes a Repository, how do I inject that Repository into the Service?

Collapse
 
jpblancodb profile image
JPBlancoDB

Hi Katie, that's a good question and sorry for not specify that in the post. So, in Startup.cs class you declare all the bindings for knowing which implementation needs to be resolved for each interface. For the actual dependency injection, you could do it by passing the members in the constructor of your class, an example:

// MyController.cs
[ApiController, Route("api/[controller]")]
public class MyController : BaseController 
{
    private readonly IMyService _myService;

    public MyController(IMyService myService)
    { 
        _myService = myService;
    }
}
// MyService.cs
public class MyService : IMyService
{
    private readonly IMyRepository _myRepository;

    public MyService(IMyRepository myRepository) -> here it gets injected
    { 
        _myRepository = myRepository;
    }
}

This is constructor injection (you also have other way like "field injection"). To summarize, you need to pass the interface via constructor and is going to be resolved to the desired class at runtime with whatever you have declared in your startup.

This allows you to have two different implementations but you are not coupled. One scenario could be that you have

IRepository with MySqlRepository and MongoDbRepository as implementations of that interface. Is recommended to always develop against an abstraction (in this case, IRepository) and resolve the desire implementation at runtime by any logic you need.

I hope this clarifies a little bit more. Let me know if it was helpful or if you need more info, I'm happy to help!