Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core - What challenges or issues may arise from using [FromServices] attribute? [closed]

I have a Controller in ASP Core MVC. I'm trying to trim down the dependency injected services in the constructor so I can start building unit tests more easily. However, I have some services being injected that are only used in one or two controller actions. For example, I inject ILocationService because in a couple of my actions, I need to lookup a country Id number and get a ISO Alpha-2 country code using a database (eg mapping ID number 1 to "CA", mapping 2 to "US", etc.)

Asp Core supports the [FromServices] attribute, so I have the option to inject ILocationService directly into two of my actions instead of injecting them in the controller constructor. The advantage for this is I don't need to always mock/inject ILocationService into my controller from every unit test and its more clear when writing unit tests which services each function depends on.

The obvious disadvantage is now its not completely obvious and clear what services my controller depends on since they are not all grouped in the constructor.

Are there any other specific challenges, issues, or points of confusion that may arise from using the [FromServices] attribute?

like image 343
Brad Avatar asked Feb 12 '19 18:02

Brad


People also ask

Why is dependency injection important?

Dependency injection helps to develop testable code, allowing developers to write unit tests easily. You can use mock databases with dependency injection, and test your application without affecting the actual database.

What is FromServices?

The FromServices attribute, when used in your controller, specifies that a parameter in an action method should be bound to a service from the services container. In other words, when you use this attribute in an action method, the services container is used to resolve dependencies at runtime.

Which of the below is a major limitation of dependency injection DI?

Disadvantages of Dependency Injection: Dependency injection creates clients that demand configuration details to be supplied by construction code. This can be difficult when obvious defaults are available. Dependency injection can make code difficult to trace (read) because it separates behaviour from construction.


1 Answers

There are a few unfortunate downsides to this type of method injection that you should consider:

  • Such [FromServices] attribute can be easily forgotten, and you will only find out when the action is invoked (instead of finding out at application start-up -or during a unit test- where you can verify the application's configuration)
  • The need for moving away from constructor injection for performance reasons is an indication that injected components are too heavy to create, while injection constructors should be simple, and component creation should, therefore, be very lightweight.
  • The need for moving away from constructor injection to prevent constructors from becoming too large is an indication that your classes have too many dependencies and are becoming too complex. In other words, having many dependencies is an indication that the class violates the Single Responsibility Principle. The fact that your controller actions can easily be split over different classes is proof that such controller is not very cohesive and, therefore, an indication of a SRP violation.

So instead of hiding the root problem with the use of method injection, I advise the use of constructor injection as sole injection pattern here and make your controllers smaller. This might mean, however, that your routing scheme becomes different from your class structure, but this is perfectly fine, and completely supported by ASP.NET Core.

From a testability perspective, btw, it shouldn’t really matter if there sometimes is a dependency that isn’t needed. There are effective test patterns that fix this problem.

like image 115
Steven Avatar answered Oct 17 '22 07:10

Steven