DDD:服务和存储库实例注入DI作为单身人士

时间:2013-10-11 22:00:07

标签: dependency-injection singleton domain-driven-design ddd-repositories

我最近对我的观点提出质疑,认为单身人士只对记录和配置有好处。使用依赖注入,我现在没有看到为什么不能将您的服务或存储库用作单例的原因。

没有耦合因为DI通过接口注入单例实例。唯一合理的论点是您的服务可能具有共享状态,但如果您考虑它,服务应该是独立的单元而没有任何共享状态。是的,他们确实注入了存储库,但您只有一种方法可以创建存储库实例并将其传递给服务。由于存储库永远不应该具有共享状态,因此我没有看到为什么它也不能成为单例的原因。

例如,一个简单的服务类看起来像这样:

public class GraphicService : IGraphicService
{
    private IGraphicRepository _rep;
    public GraphicService(IGraphicRepository rep)
    {
       _rep = rep;
    }

    public void CreateGraphic() 
    {
      ...
      _rep.SaveGraphic(graphic):
    }
}

除了没有更改或拥有自己状态的存储库之外,服务中没有共享状态。

所以问题是,如果您的服务和存储库没有任何状态并且只通过接口,配置或其他任何实例化的方式传入,那么为什么不将它们作为单例传递给他们

2 个答案:

答案 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时它不会增加太多的价值。