Dependency injection approach for object, used only in a single method
I'm migrating an old ASP.NET 4.7.2 MVC application to ASP.NET Core and wish to learn more of the DI approach, since it's already deeply integrated into the Core framework. However, so far I've encountered some issues utilizing it. I understand DI is supposed to be used across the call chain, with every class having its dependencies injected. But what if you want to use an instance of a class only in a specific method of your current one? Are you supposed to inject it for the whole class, wasting performance on potentially heavy instantiations when it's not necessary?
Here's an example;
I have a class that has many methods, each doing its own thing. Assume that class cannot be split into different smaller classes, maybe it's a controller. The inner class expects a logger with its own category. Now, I could instantiate it in the method and pass the existing logger, but that logger would have the wrong category (
TestClass
instead of InnerClass
). I could also inject an IServiceProvider
, however as I understand that is an anti-pattern and shouldn't be done when implementing DI. I could also introduce a [FromService]
attribute, however that is also an anti-pattern, plus it only works for controller actions called from the environment, not private methods.
What is the best approach here? Is the answer really injecting it for the whole class? What if the inner class is an ORM helper, do I need to create a DB connection every time?18 Replies
P.S. One approach would be to indeed separate the method to a different object. However, doesn't that just kick the can down the road? If you would need to then inject that object to call the method, doesn't the injection still happen for the whole
TestClass
?for me this decision is purely based on context.
as a question for you to answer yourself: does TestClass honor the SingleResponsibility principle?
from experiences, the thing you try to do often will be a 'no' as answer.
It does not, however in the context this
TestClass
is a controller, and to my understanding they usually serve as a hub for routing requests to business logicOh yeah you found the reason why i dont work with controllers anymore 😄
I could of course separate out this controller, but as per my P.S. I feel this would just kick the can down the road, as the derived new class would still need to be instantiated somewhere
the default usually was to inject it and take the overhead as long as its not problematic.
but yeah its just what in my environments i worked in was done.
is the minimal api approach not feasable?
then everything is instanciated only if required(based on lifetime).
Unfortunately this would result in hundreds of
ApiController
s, since the application is quite large, and that would make supporting it even more difficult than if I just used a IServiceProvider
, for exampleto answer this:
you could. then the class would only be instanciated in that call that needs it, but then the controller scheme is unclear.
we currently rebuild an api (net framework 3.5) with 450 calls as minimal api project.
0 regrets.
we there can lay out the route structure in folders and use a IEndpoint interface to scan the assembly at startup and map all found classes.
This sounds like a better approach. However, I don't know how much of it can be implemented in my situation, since I'm trying to not have to rewrite the entire application during this migration
I posted the question to StackOverflow as well and got an interesting comment about Lazy<T> injections
Currently reading up on it, give me a moment
you can mix and match controllers with minimal api. (not a good idea, but technically possible)
I feel like this would be an even worse anti-pattern than just using a
IServiceProvider
😄yeah 🙂 its about the same place in hell.
Okay, so this lazy instantiation seems like a good approach to my problem. It basically works like
IEnumerable<T>
does for collections: it injects placeholder values for the objects needed, then instantiates them the first time they are used. This seems like exactly what I need, and doesn't add obvious drawbacks. I'm going to read up on it some more to learn if it's also considered an anti-patter, bad practice or anything similargreat. could you be so kind and ping me with your research results (and maybe sources then)?
not something i expect to need often, but cant hurt to have in my toolbelt.
Absolutely. Give me a moment to respond to the guy in SO and I'll post everything here.
no rush.
Stack Overflow
Dependency injection approach for object used only in a single method
I'm migrating an old ASP.NET 4.7.2 MVC application to ASP.NET Core and wish to learn more of the DI approach, since it's already deeply integrated into the Core framework. However, so far I've
Medium
Lazy in Dependency Injection with C#Â .Net Core
I am going to discuss a use case of Lazy keyword in C# in the context of Dependency Injection (DI) or Inversion of Control (IoC)
I'm going to be testing this solution and I'll report back with any problems I find with the approach. Thank you very much for taking the time!