0

let's say I have following code:

import (
   handlerA "some/path/handlerA"
   handlerB "some/path/handlerB"
   handlerC "some/path/handlerC"
   handlerD "some/path/handlerD"
   ....
   handlerZ "some/path/handlerZ"
)

func DoSomething(a handlerA.A, b handlerB.B, c handlerC.C, d handlerD.D..., z handlerZ.Z) {
   a.DoA()
   b.DoB()
   c.DoC()
   d.DoD()
   ....
   z.DoZ()
}

I obviously made the function DoSomething(...) mockable, as this makes my function unit testable. But because of that I get way to many arguments because of all the dependencies my function needs to get injected.

Is there a better way in Golang to handle many dependencies?

5
  • 1
    This looks more like a design issue. Having that many dependencies is a code smell and indicates that the function may be doing too much. Some of those dependencies may need to be aggregated into a service. Commented Nov 26, 2019 at 11:45
  • I exaggerated on purpose. I would never code something like that. But having functions with two or three dependency injection arguments are quite common I would say. Especially if you don't got enough time for refactoring code because of deadlines or something like that. Commented Nov 26, 2019 at 11:54
  • You might want to look at github.com/jwells131313/dargo which is a dependency injection framework for golang Commented Nov 26, 2019 at 12:45
  • Or github.com/google/wire which is first-party, though not part of the stdlib. Commented Nov 26, 2019 at 15:01
  • What is the difference between .DoA() and .DoB()? They both could be just .Do(). Now it is possible to define an interface like type Doer interface { Do() } and the signature can change to DoSomething(...Doer). Commented Nov 26, 2019 at 23:42

1 Answer 1

2

One way to handle many injections would be to use a struct as wrapper:

type SomethingDoer struct {
  a handlerA.A,
  b handlerB.B,
  c handlerC.C,
  d handlerD.D,
  ...
  z handlerZ.Z,
}

func (sd SomethingDoer) DoSomething() {
   sd.a.DoA()
   sd.b.DoB()
   sd.c.DoC()
   sd.d.DoD()
   ....
   sd.z.DoZ()
}

I just figured that out by reading the question by myself again...

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

2 Comments

This doesn't reduces the dependencies, it just groups them into a struct. Having to provide a struct value, you also need to initialize it with the same dependencies.
Yes, but in that way I would avoid having to many parameters in functions, which would make the code more readable I guess. Also imagine if one would need to call this function on multiple occasions: With the wrapper you only would need to inject dependencies once.

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.