【发布时间】:2010-11-03 15:29:47
【问题描述】:
我们的应用程序中有一个非常常见的对象。在这种情况下,我们将其称为 Ball。球工作正常,但在某些配置中它们的作用不同。目前是这样设置的:
class Ball
{
private static readonly bool BallsCanExplode;
static Ball()
{
bool.TryParse(ConfigurationManager.AppSettings["ballsCanExplode"],
out BallsCanExplode);
}
public Ball(){}
}
这在实践中完全没问题。如果配置是球可以爆炸,它们会爆炸,如果不是,则不会。问题是它是完全不可测试的。我还没有找到一种保持它可测试并且仍然易于实例化的好方法。
最简单的解决方案是将球和配置解耦:
class Ball
{
private readonly bool CanExplode;
public Ball(bool canExplode);
}
这样做的问题是,曾经在 Ball 类中孤立的依赖关系现在已经蔓延到每个生成 Ball 的类中。如果这被注入了依赖项,那么爆炸球的知识必须到处注入。
BallFactory 也存在同样的问题。虽然每个类都可以转到new Ball(),但它现在必须知道必须在任何地方注入的 BallFactory。另一种选择是使用已经嵌入应用程序的服务定位器:
class Ball
{
private readonly bool CanExplode;
public Ball()
{
CanExplode = ServiceLocator.Get<IConfiguration>().Get("ballsCanExplode");
}
}
这仍然保留了球中的配置依赖关系,但允许注入测试配置。尽管球被大量使用,以至于在每次new Ball() 调用时定位服务似乎有点过头了。
保持这种可测试性以及易于实例化的最佳方式是什么?
注意:应用中既有依赖注入框架,也有服务定位器,都是经常用到的。
【问题讨论】:
-
那些 D.I. Ninject 之类的库有帮助吗?
-
您似乎知道依赖注入选项,但不想遵循它们。因此,您最好的选择是添加一个构造函数进行测试: public Ball(bool CanExplode)
标签: c# design-patterns configuration dependency-injection