Dependency injection through constructors or property setters?
I'm refactoring a class and adding a new dependency to it. The class is currently taking its existing dependencies in the constructor. So for consistency, I add the parameter to the constructor.
Of course, there are a few subclasses plus even more for unit tests, so now I am playing the game of going around altering all the constructors to match, and it's taking ages.
It makes me think that using properties with setters is a better way of getting dependencies. I don't think injected dependencies should be part of the interface to constructing an instance of a class. You add a dependency and now all your users (subclasses and anyone instantiating you directly) suddenly know about it. That feels like a break of encapsulation.
This doesn't seem to be the pattern with the existing code here, so I am looking to find out what the general consensus is, pros and cons of constructors versus properties. Is using property setters better?
Well, it depends :-).
If the class cannot do its job without the dependency, then add it to the constructor. The class needs the new dependency, so you want your change to break things. Also, creating a class that is not fully initialized ("two-step construction") is an anti-pattern (IMHO).
If the class can work without the dependency, a setter is fine.
The users of a class are supposed to know about the dependencies of a given class. If I had a class that, for example, connected to a database, and didn't provide a means to inject a persistence layer dependency, a user would never know that a connection to the database would have to be available. However, if I alter the constructor I let the users know that there is a dependency on the persistence layer.
Also, to prevent yourself from having to alter every use of the old constructor, simply apply constructor chaining as a temporary bridge between the old and new constructor.
public class ClassExample
{
public ClassExample(IDependencyOne dependencyOne, IDependencyTwo dependencyTwo)
: this (dependnecyOne, dependencyTwo, new DependnecyThreeConcreteImpl())
{ }
public ClassExample(IDependencyOne dependencyOne, IDependencyTwo dependencyTwo, IDependencyThree dependencyThree)
{
// Set the properties here.
}
}
One of the points of dependency injection is to reveal what dependencies the class has. If the class has too many dependencies, then it may be time for some refactoring to take place: Does every method of the class use all the dependencies? If not, then that's a good starting point to see where the class could be split up.
Of course, putting on the constructor means that you can validate all at once. If you assign things into read-only fields then you have some guarantees about your object's dependencies right from construction time.
It is a real pain adding new dependencies, but at least this way the compiler keeps complaining until it's correct. Which is a good thing, I think.
链接地址: http://www.djcxy.com/p/77780.html上一篇: 如何解释依赖注入到5
下一篇: 通过构造函数或属性设置程序进行依赖注入?