Skip to content
Home Β» Blog Β» Inject Services Directly To Action Methods in .NET

Inject Services Directly To Action Methods in .NET

How to inject directly into your controller 𝘒𝘀𝘡π˜ͺ𝘰𝘯 methods in .π—‘π—˜π—§? πŸ€” β€” Without using the constructor injection.

While the traditional constructor injection is widely used, another gem πŸ’Ž in the DI toolbox is the [FromServices] attribute. It allows you to inject your service dependency directly into action methods without using the constructor approach.

It works seamlessly with the built-in DI container and provides a more concise and declarative way of handling dependencies within specific methods.

Pros and Cons

πŸ‘ Pros of [FromServices] attribute: 
Cleaner and more concise code without the constructor usage. ✨
More control in certain scenarios where you may only require specific services for a particular action method.
– It’s an elegant solution when constructor injection is impossible, like with ActionFilters or ActionResults.

πŸ‘Ž However, there are also a few cons:
– Injected dependencies are a little more obscure compared to the constructor approach.
– It could be more difficult to inject services in a testing context. πŸ§ͺ

The [FromServices] attribute presents an interesting alternative to constructor injection. Its concise nature and flexibility make it an attractive option for certain scenarios.

However, it’s essential to strike a balance between using [FromServices] and constructor injection to maintain code readability and testability.

In Practice

Let’s compare both, starting with the constructor injection:

public class CustomersController : Controller
{
    private readonly ICustomerService _customerService;

    public CustomerController(ICustomerService customerService)
    {
        _customerService = customerService;
    }

    public IEnumerable<CustomerDto> GetCustomers()
    {
        // Sample code, no dto mapping
        return _customerService.GetCustomers();
    }
}

And now [FromServices] attribute:

public class CustomersController : Controller
{
    public IEnumerable<CustomerDto> GetCustomers([FromServices] ICustomerService  customerService)
    {
        // Sample code, no dto mapping
        return _customerService.GetCustomers();
    }
}

My Feedback

In practice, you could have too many dependencies injected into your constructor and want a lighter approach to inject only what you need using the [FromServices] attribute. It’s also probably a sign that you have to review your design and possibly have a more loose coupled solution with a better separation of concernsβ€” the Mediator pattern (MediatR) could be helpful in this case.

Finally, even if I don’t expect any noticeable gap, comparing performances with a benchmark could be interesting. My “by default” approach is still to inject dependencies through the constructor and switch to a more adapted design if the number of dependencies explodes.

Do you have any tips or 𝘦𝘹𝘱𝘦𝘳π˜ͺ𝘦𝘯𝘀𝘦𝘴 with [π—™π—Ώπ—Όπ—Ίπ—¦π—²π—Ώπ˜ƒπ—Άπ—°π—²π˜€] attribute?

References