7

I was wondering if there is a "cleaner" solution to using dependency injection with binding to classes with a lot of arguments, since according to Robert C.Martin's Clean Code, it's better not to use more than 3 arguments... Any other solutions, ideas (and examples?)

6
  • 2
    Do you specifically mean constructor injection when a class has many dependencies? Commented Sep 23, 2014 at 13:05
  • probably doesn't answer your question, but i think it's quite clean to pass an array as a single argument that actually contains lots of different pieces of information. I've seen this done a lot in javascript, with jQuery being a typical example. Not di, but it does clean up the issue of lots of arguments. Commented Sep 23, 2014 at 13:09
  • 1
    if you do seem to have lots of dependencies then I would ask if your design is too tightly coupled. Commented Sep 23, 2014 at 13:10
  • @David - Yes, I mean constructor injection Commented Sep 23, 2014 at 14:26
  • 3
    Many arguments in a constructor usually means the class does too many things. If not though, perhaps you need to encapsulate some of the related dependencies into a smaller class that can be passed in as a single argument. Can't really help without a sample though. Commented Sep 24, 2014 at 14:18

2 Answers 2

5
Dependency Injection != Lot of arguments

The number of arguments you are going to use depends on your personal code design, with DI you focus on dependencies you need to achieve something, you will of course need at least those dependencies even if you don't code a class in terms of "Dependency Injection/IoC pattern". If you have too many arguments you probably have to rethink in someway your design.

If you are in doubt think in terms of maintenability.

"If I have to change something, where it will be? And if I do that change, how many other places will be touched by the change?"

There are possible workarounds, just to say few:

  1. Wrap 2 or more dependencies as a new dependency (chances are high that when you need multiple dependencies you will not need the whole API of those dependencies and hence you can hide part of it behind a new interface.. )
  2. As Spock said you can create a "parameter" object (implementation left to you: parameter list or a struct of objects).

Depending also on your programming language you'll probably find more usefull certain solutions instead of others (option 1 may be more suitable with languages like C++ where each dependency can increase compile time heavily, while option 2 seems likely to be used with languages like PHP because requires less coding and effort by the user).

Sign up to request clarification or add additional context in comments.

Comments

4

My take on.. Regardless of whether you use Constructor arguments or routine arguments, it is best to avoid lot of parameters passed as arguments.

Even Robert C.Martin's Clean Code, says it's better not to use more than 3, it is just a guideline. In reality this can be changeling as you may need to exceed this limit for number of reasons. For example, if you have multiple constructors, some do like parameters listed nicely so the API discoverable - that also means that the list of parameters would never change.

But this is not the case in most occasions that the parameters may change and re factoring and becomes harder if you have long parameters list. I use arrays, or contain objects, so the change would just that object.

So the preference is to use less parameters 3/4 max, but if you go overboard, create an object you can pass around. Whilst this would cater most cases, sometimes you may have to have the long parameter list IMO.

3 Comments

Is it possible to provide a small example how to set this into an object?
What I did now is: I created a abstract class and in that constructor, I use the Kernel.Get<...> so I don't have to pass them inside my constructor. Is that a better solution? My other classes derive from the abstract class
In that case you need contextual binding. In general IoC/DI frameworks assume 1 interface = 1 concrete class. Most frameworks allows polymorphic binding, but you don't need it since you can elengatly workaround. When you need multiple implementations at once using contextual binding may cause more bugs than finding an alternative solution. (by Polymorphic I mean different implementations coexisting within same interface)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.