Ale*_*lex 6 dependency-injection
使用依赖注入时,您注入哪些依赖项?
我以前注入了所有依赖项,但是在执行TDD时发现通常有两种类型的依赖项:
一种方法是注入这样的所有依赖项
public ClassWithExternalDependency(IExternalDependency external,
IExtractedForTestabilityDependency internal)
{
// assign dependencies ...
}
Run Code Online (Sandbox Code Playgroud)
但我发现这可能会导致DI注册表中的依赖性膨胀.
另一种方法是隐藏像这样的"可测试性依赖"
public ClassWithExternalDependency(IExternalDependency external)
: this (external, new ConcreteClassOfInternalDependency())
{}
internal ClassWithExternalDependency(IExternalDependency external,
IExtractedForTestabilityDependency internal)
{
// assign dependencies ...
}
Run Code Online (Sandbox Code Playgroud)
这是更多的努力,但似乎更有意义.缺点不是所有对象都在DI框架中配置,从而打破了我听过的"最佳实践".
你会提倡哪种方法?为什么?
我相信你最好注入所有依赖项。如果它开始变得有点笨拙,这可能表明您需要稍微简化一些事情或将依赖项移到另一个对象中。边走边感受设计的“痛苦”确实很有启发。
至于注册表中的依赖项膨胀,您可能会考虑使用某种传统的绑定技术,而不是手动注册每个依赖项。一些 IoC 容器内置了基于约定的类型扫描绑定。例如,以下是我在使用 Ninject 的 Caliburn WPF 应用程序中使用的模块的一部分:
public class AppModule : NinjectModule
{
public override void Load()
{
Bind<IShellPresenter>().To<ShellPresenter>().InSingletonScope();
BindAllResults();
BindAllPresenters();
}
/// <summary>
/// Automatically bind all presenters that haven't already been manually bound
/// </summary>
public void BindAllPresenters()
{
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
IEnumerable<Type> presenterImplementors =
from t in types
where !t.IsInterface
&& t.Name.EndsWith("Presenter")
select t;
presenterImplementors.Run(
implementationType =>
{
if (!Kernel.GetBindings(implementationType).Any())
Bind(implementationType).ToSelf();
});
}
Run Code Online (Sandbox Code Playgroud)
尽管我有数十个结果和演示者,但我不必明确注册它们。
| 归档时间: |
|
| 查看次数: |
307 次 |
| 最近记录: |