我最近对我的观点提出质疑,认为单身人士只对记录和配置有好处。使用依赖注入,我现在没有看到为什么不能将您的服务或存储库用作单例的原因。
没有耦合因为DI通过接口注入单例实例。唯一合理的论点是您的服务可能具有共享状态,但如果您考虑它,服务应该是独立的单元而没有任何共享状态。是的,他们确实注入了存储库,但您只有一种方法可以创建存储库实例并将其传递给服务。由于存储库永远不应该具有共享状态,因此我没有看到为什么它也不能成为单例的原因。
例如,一个简单的服务类看起来像这样:
public class GraphicService : IGraphicService
{
private IGraphicRepository _rep;
public GraphicService(IGraphicRepository rep)
{
_rep = rep;
}
public void CreateGraphic()
{
...
_rep.SaveGraphic(graphic):
}
}
除了没有更改或拥有自己状态的存储库之外,服务中没有共享状态。
所以问题是,如果您的服务和存储库没有任何状态并且只通过接口,配置或其他任何实例化的方式传入,那么为什么不将它们作为单例传递给他们
答案 0 :(得分:3)
如果您正在使用Singleton模式,即类的静态属性,那么您就会遇到紧耦合问题。
如果你只需要一个类的一个实例并且你正在使用DI容器来控制它的生命周期,那么这不是一个问题,因为没有任何缺点。该应用程序不知道有单独的单一,只有DI容器知道它。
底线,类的单个实例是有效的编码要求,唯一的问题是如何实现它。 Di Container是最好的方法。 Singleton模式适用于那些你不太关心可维护性和测试的快速应用程序。
答案 1 :(得分:0)
有些项目在依赖注入填充之前使用单例进行依赖查找。例如iBATIS jpetstore如果我没有弄错的话。方便你可以像
那样全心全意地获得你的依赖public class GraphicService : IGraphicService
{
private IGraphicRepository _rep = GraphicRepository.getInstance();
public void CreateGraphic()
{
...
_rep.SaveGraphic(graphic):
}
}
但这会损害可测试性(因为不容易用测试双精度替换依赖性)并引入隐式强依赖性(IGraphicService依赖于抽象和实现)。
Dependeny注射剂可以解决这些问题。我不明白为什么在你的情况下不能使用单例,但在使用DI时它不会增加太多的价值。