-1

I was tonight thinking what it tells about design and architecture of classes with many injected objects. I am taking into consideration setter and constructor injection specifically.

Setter injection proponents always use an argument of constructor injection complexity in opposition to setter simplicity especially in cases where the number of parameters in constructor grows, but that is a different topic.

I would think, that a large number of injected parts suggest a breach of single responsibility of the object. There could be special snowflakes, but in general good metric, I think.

Now how to fight it especially in cases where the vertical depth of constructors is bigger than let's say 3?

I am thinking about some guidance\rules to fight these cases.

Explanation: Vertical Depth

Let's say that we have some complex architecture, where some class UniversalHelper/IUniversalHelper is created early in the root or close to the root and the instance is permeating throughout the graph deeper and deeper. I do not consider loggers as such objects, they do have specific purpose must permeate through whole architecture, but something like universal data access. It feels that something like specific data managers for specific data access cases should be used and then more general object UniversalHelper would not be permeating through the architecture, its vertical depth would be limited instead horizontal depth would grow in one specific point, where UniversalHelper would be used to create specific data managers, objects with refined, more constrained or limited responsibility towards single responsibility goal.

Obviously, where is allowed to one universal object to permeate whole architecture, sooner or later there will be two, three, five :). It is logical because it feels to seasoned developers on the given project as a useful, right and tested way of life and for new developers joining specific project it is a sign, it was always done this way, if you do that in the same manner, it has higher probability to pass code review from seasoned colleagues on the project...

ipavlu
  • 129
  • 6
  • 1
    Can you clarify the relevance of the vertical depth of constructors (maybe even clarify the concept itself, too) in regard to too many constructor parameters? – larsbe Sep 26 '17 at 13:32
  • 2
    The only way this question becomes answerable is if you can provide a specific case that we can evaluate on its merits. Otherwise, this is a "convince my coworkers" question with no specific goal other than as a parameter counting exercise. There's no rule of "maximum number of constructor parameters" to follow; you have to decide whether or not the benefits of many parameters exceed the costs on a case-by-case basis. If you're using DI, does the number of constructor parameters even matter? – Robert Harvey Sep 26 '17 at 15:11
  • 1
    Strongly related, if not exact duplicate: [How many injections is acceptable in one class when using dependency injection?](https://softwareengineering.stackexchange.com/questions/313697) – Robert Harvey Sep 26 '17 at 19:34
  • 1
    Sounds like your use of dependency injection is the smell. – Frank Hileman Sep 29 '17 at 19:44
  • Hi, I had hope that some ideas would accumulate during my absence:). To further explain what I mean by vertical depth I will edit the question... – ipavlu Oct 15 '17 at 15:26
  • Closely related: [Are so called “cross-cutting concerns” a valid excuse to break SOLID/DI/IoC?](https://softwareengineering.stackexchange.com/q/318395/1204) – Robert Harvey Oct 15 '17 at 23:45
  • See also https://en.wikipedia.org/wiki/Aspect-oriented_programming – Robert Harvey Oct 15 '17 at 23:47
  • and https://msdn.microsoft.com/en-us/library/ee658105.aspx – Robert Harvey Oct 15 '17 at 23:48
  • Possible duplicate of [How many injections is acceptable in one class when using dependency injection?](https://softwareengineering.stackexchange.com/q/313697/1204) – Robert Harvey Oct 15 '17 at 23:56

1 Answers1

1

You can, in principle, do dependency injection in two ways: By passing all the injected classes to the constructor creating an instance, or by having some global method that provides all classes that could be injected to anyone who needs it. (I'm sure someone can find a third way :-)

The latter method means an instance just has to grab exactly those injected classes that it needs itself, and that it therefore knows about.

The first method has the problem that if the instance has dependencies (if it creates other instances), then it has to pass the right injected classes to the constructors of these instances. And these might be injections that the instance doesn't care about and shouldn't have to care about.

Worst case: You add a class I to be injected to instances of one class A. So then any constructor creating those instances of A needs to pass that injection I. So all classes B whose instances create instances of A need I. So all classes C whose instances create instances of B need I. And so on.

That's the reason why I very much prefer "every man for himself": Any instances needing an injection should get it themselves from somewhere.

gnasher729
  • 42,090
  • 4
  • 59
  • 119