Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency injection of context class in constructor

I have a service that uses ApplicationContext. So I want to use dependency injection to have the application give me the context. So I put in in the construction

Private _context;

// Constructor
public Service(ApplicationContext context) {
    _context = context
}

The problem is when I initialize this service I have to pass it a context so that's not really dependency injection is it?

Is there a way to get the context injected without putting it in the constructors parameters?

****** EDIT *****

I'm sorry that I didn't give enough information the first time. Let me try and explain it better. I have a service which i will just call service for now. It reads the header variables in a request and return xml base on their values. I newup an instance in each different method of a controller as they may have different values for the header variables. I would like the context injected into the service instead of the controller so i can say this:

Service service = new Service(Request);

Instead of this:

Service service = new Service(Request, Context);

The reason being the service is doing all the work with the context the controller need not know anything about it. The code I have will work but it would be great if i could get this working the way i explained.

If we could still [FromServices] on a property. That would be the perfect solution. Unfortunately that was taken away. Which would only leave injecting the context into the constructor for either the service or the controller. In which case I would still have to pass the context as an argument to the service.

Is there a way to inject the context into the services constructor and avoid having to pass it as an argument upon creation?

There may be a more elegant solutions which I would be happy to consider.

like image 774
Dblock247 Avatar asked Feb 17 '16 02:02

Dblock247


2 Answers

I your controller have for example only one method then introduction of separate constructor just for saving ApplicationContext have no advantage. The context will be already hold inside of the HttpContext and you can use [FromServices] attribute as the additional parameter of your controller action. See the documentation. For example

[Route("api/[controller]")]
public class MyController : Controller
{
    [HttpGet]
    public async IEnumerable<object> Get([FromServices] ApplicationContext context,
                                         MyType myMainParam)
    {
        ...
    }
}

RC1 allows to define property with [FromServices] for getting the information from dependency injection, but RC2 will don't more allow this (see the announcement). You can find examples of both styles in the answer.

like image 111
Oleg Avatar answered Nov 15 '22 07:11

Oleg


It is dependency injection over constructor. With DI, you shouldn't initialize your service directly. You should register your Service and ApplicationContext in Startup.cs.

When you need your Service, you should inject it over constructor into a controller, and DI chain will automatically inject instance of ApplicationContext into the Service.

Of course, if you don't need your service for each method in a controller, you can initialize it into method as @Oleg wrote.

like image 44
Igor Avatar answered Nov 15 '22 09:11

Igor