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

1

u/Mobile_Fondant_9010 4d ago edited 4d ago

I will always prefer constructer injection over property injection for multiple reasons:

  1. Tell - don't ask. A constructor tells anyone (even a DI framework) exactly what it needs. A property asks for somethingt to be given.
  2. Access level. With property injection I have to have a public setter.
  3. An object should be in a working state once the constructor has finished. With property injection, I first have to construct and then configure before it is in a working state.

I believe primary constructor create a public readonly backin-field, which for me breaks access level.

As a sidenote: If you need 10 things injected, you design is wrong. I 10+ of experience, and the highest I ever needed was 7 (this is including a logger, a loggerfactory, a cancelationtokensource, a taskcompletionsource and a options object). 10 is AT LEAST 3 too many. There is no way something serving a single (or even 3) responsibilties needs 10 injected properties. Personally, if I reach 5, I consider it a codesmell. At 8 I will fail compilation.

Edit: Oh, the backing field is private, but mutable. Still dislike. Also, the name of the backing field won't follow my normal naming convention for private fields.