我有一个依赖于另一个类的单例,所以我想注入这个依赖项以使其可以单元测试。由于没有办法在单例上使用构造函数注入,我想我应该使用setter injcetion而不是我真的不喜欢它,因为在某些时候某人(可能是我自己)将忘记调用setter。您当然可以将依赖对象注入到单例的getInstance方法中,但这也非常难看。有没有更好的解决方法(不使用像IoC容器这样的工具)?
public class Singleton {
private ISomeDependency _dependency;
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return INSTANCE;
}
...
}
答案 0 :(得分:3)
单例设计模式是一个很大的反模式,因为没有办法在单例中注入依赖项。但是,这并不意味着在应用程序的生命周期内无法使用单个实例,但是您不应该使用单例设计模式。特别是在使用依赖注入时,没有理由使用这种设计模式。
只需在依赖于它的类型中注入该类型的实例作为构造函数即可。这使您可以在应用程序的顶部构建对象图并控制其中的生活方式,并将依赖项注入该实例。
该类的设计应该像任何其他类一样:
public class SomeService : ISomeService
{
private ISomeDependency _dependency;
public ISomeService(ISomeDependency dependency)
{
_dependency = dependency;
}
// ISomeService members here
}
依赖注入框架将允许您非常轻松地定义任何类型的生活方式。对于简单的应用程序,您仍然可以手动执行此操作。
答案 1 :(得分:0)
您可以使用依赖注入容器(如Spring.Net,MS Unity等)来获取依赖项的具体类型。
public class Singleton {
private ISomeDependency _dependency = Container.Resolve<ISomeDependency>();
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return INSTANCE;
}
...
}
现在你有了单身人士之外的控制权。