问题
Should dependencies be stored to private fields or properties with private setters and public getters? This applies to constructor DI.
To be clear, in the property example, I would not expect these to be added to an accompanying interface unless it made sense - i.e. they would only be visible in the implementation type:
interface IFoo {
void DoSomething();
}
class Foo : IFoo {
private readonly IService dependency;
public Foo(IService dependency) {
this.dependency = dependency;
}
}
class Bar : IFoo {
public Foo(IService dependency) {
this.Dependency = dependency;
}
public IService Dependency { get; private set; }
}
回答1:
I would always recommend private readonly
fields, as long as there is no need to access the dependency from outside of the object. Treat your objects as "black boxes" and put as little as possible in their public interfaces. This practice is better known as encapsulation principle or information hiding and also applies to injected dependencies: The less you expose, the more you reduce tight coupling between your class and your class' users.
Another principle that should be mentioned is modeling the behavior of objects: Tell, don't ask. If you need to get something done, ask the object to do it for you. It will use its dependencies in the process. Asking for properties and doing the work yourself should only be the first choice for data objects (DTOs).
This is also the reason for using constructor injection in the first place: Everybody would be doing property injection instead, if exposing dependencies as properties was best practice, as this would mean less code (we wouldn't need the constructors then).
回答2:
It depends purely upon whether you need to allow the consuming object to change the dependency during the lifetime of the consumed object.
Using DI on the constructor is setting you up for two things:
- it is defining a contract, saying "this class needs this specific dependency to operate"
- it allows you to easily manipulate the dependency that is used by injecting a different implementation (i.e. injecting mock implementations when unit testing, or you have a view that could take any of several viewmodels when using MVVM, etc.)
If you like to keep your objects immutable, then a public getter and private setter is the way to go. However things are not always that simple - an object may have a long life, and it is easy to have a scenario where you need to change the dependency.
TL;DR: it depends. When you write large applications you'll find that you need to mix your approach - you'll have dependencies defined in the ctor(s), but for some of them you'll need the facility to change them after the object has been created.
回答3:
I agree with @Frank you have to keep it private it is better for Testing and it give you a better object encapsulation.
imagine you have an interface need to access only the Bar class in this case your customer can do something Bar.Dependency.BadMethodBurnTheDevice();
来源:https://stackoverflow.com/questions/27839935/should-injected-dependencies-be-publicly-accessible-or-private