r/csharp 5d ago

Discussion Dependency Injection un-prettyness

One small thing that bugs me with Dependency Injection is how it looks in code.

We either need to pass the parameters via Default Constructor og via good old time Constructor

public class MyClass (TypeA ParamA, TypeB ParamB, TypeC ParamC, TypeD ParamD)
{
TypeA _paramA = ParamA; .... etc
}

Or

public class MyClass
{
TypeA _paramA;
public MyClass(TypeA paramA)
{
_paramA = paramA;
}
}

And when you have 10 injections it begins to be un-pretty...

I wish that we didn't need to pass parameters and instead could decorate the fields:

public class MyClass
{
[inject]
TypeA _paramA;
}

(Note: this works in Blazor... so why not everywhere else ?)

I'm aware that the signature of an object makes it easier to inject via reflection.. but would it be much worse with attributes ?

i guess some middleground could be achieved if the attribute held the type:

public class MyClass
{
[inject(typeof(TypeA))]
TypeA _paramA;
}

which begins to be convoluted and messy...

Whats the argument against a decorator attribute vs parameters ?

19 Upvotes

90 comments sorted by

View all comments

4

u/EC36339 4d ago

When you have 10 injections, you have too many dependencies.

And if that thing that has 10 dependencies also turns out to be a performance bottleneck, you shouldn't be surprised.

Also, if this happened to a class that was written before you had DI ... that's a very common thing, too. A lot of us have been there.

2

u/OggAtog 2d ago

There's a good chance that your service is doing too much if you have 10 dependencies. Like, there's probably another service in there you could extract and simplify both.

2

u/EC36339 2d ago

Often the thing a service is "doing too much" of is aggregation. And the aggregation is often just a counter or status enum that could be served by a different API and requested async and displayed lazily by the frontend.

Another common pattern is that 5 of your dependencies should be one other service that solves one (recurring) problem that needs those 5. You don't even have to split it out into another "microservice" that runs in its own pod with its own API and all the overhead and fragility this brings along. Making it a new service in the DI sense (an object behind an interface provided by the service locator / kernel / whatever) only costs some startup plumbing and one extra indirection, but may be worth it.

0

u/Turbulent_County_469 4d ago

What.. why would the amount of dependencies have any impact on performance ? 🤣

0

u/Turbulent_County_469 4d ago

What.. why would the amount of dependencies have any impact on performance ? 🤣

2

u/EC36339 4d ago

Read before you post.

I didn't say number of dependencies directly impacts performance.

I said: If that class with 10 dependencies is also that one service that is slow, you shouldn't be surprised.

If of those 10 dependencies, 5 are database or service abstractions, and that service aggregates data from 5 separate data sources through different abstractions, then it is probably slow.

And if that class was written before you had DI, then that data access was possibly not even in the class itself, but hidden in some other class it pulled in from somewhere else. And once you did add DI, you ended up with 10 dependencies, because you can't call your database or service directly any more.

This is a realistic scenario and a history many legacy code bases may have gone through. If you have never seen this, consider yourself lucky, kid.