If I am writing up a class with more than 1 constructor parameter like:
class A{
public A(Dependency1 d1, Dependency2 d2, ...){}
}
I usually create a "argument holder"-type of class like:
class AArgs{
public Dependency1 d1 { get; private set; }
public Dependency2 d2 { g开发者_如何学运维et; private set; }
...
}
and then:
class A{
public A(AArgs args){}
}
Typically, using a DI-container I can configure the constructor for dependencies & resolve them & so there is minimum impact when the constructors need to change.
Is this considered an anti-pattern and/or any arguments against doing this?
This does open the door for it appearing that your dependencies are optional. By having properties for each of the dependencies for your AArgs class, someone can think they only need to fill in Dependency1, and everything will work as expected.
By explicitly listing all of your dependencies individually, you give a clear contract about what is needed for your class to function. If you have so many dependencies that the constructor is cumbersome, that should be considered a smell, as your class may be doing too much.
Mark Seemann has blogged about this.
You are passing in an aggregate of dependencies, instead of each dependency by itself--basically it's a refactoring. Mark argues that by doing this, you are making things in your domain explicit which were previously implicit.
My only concern is that your dependency holder class AArgs
may disguise the fact that you have a large number of dependencies, and thus that the class you're constructing perhaps has too many responsibilities.
If your dependency holder class AArgs
typically has few members (say, 3 or less) then that's not a problem.
Well I wouldn't go so far as to call it an anti-pattern, but if a developer needed to make changes to your code base it would be confusing to figure out what the constructor needs, so "Just to be Safe" they could just pass all the dependency objects into the constructor. Yikes! Its one of those abstractions that could be really abused.
精彩评论