干净架构中的存储库模式是否违反了依赖倒置原则?

时间:2019-03-12 20:34:04

标签: c# oop design-patterns .net-core clean-architecture

根据我所看到的内容,干净的体系结构假设您有一些对持久性一无所知的实体,尽管在它们驻留的同一层中可能存在一个接口,该接口的目的是就实体的方式达成约定读取/更新/删除。

// project Core
public class CarModel
{
    public string Name { get; set; }

    public void SomeImportantBehavior {}
}

public interface ICarModelRepository 
{
    CarModel FindByName(string name);
    CarModel Add(CarModel carModel);
}

与此同时,另一层将保留接口的实现:

// project Infrastructure or Persistence
public class CarModelRepository : ICarModelRepository
{
    public CarModel FindByName(string name)
    {
        return new CarModel { Name = name }; // the implementation is not really important here
    }

    public CarModel Add(CarModel carModel) {
        // somehow persist it here
        return carModel;
    }
}

所以我有一个问题:存储库实现是否违反DiP原则?因为它不仅取决于抽象,还取决于具体的实现(在这种情况下为CarModel)?

另一个示例是here

P.S。 CarModel是具有行为的域模型。

1 个答案:

答案 0 :(得分:1)

您有点遗漏了依赖倒置原则。该原理应反映不同模块之间的分离。换句话说,您不应在需要它们的地方实例化您的对象,而应将它们作为参数接收。这是dependency injection的基本原则。

为清楚起见,假设您有一个使用Controller的类Repository。如果没有DI,一开始它看起来像这样:

class Controller
{
    private CarModelRepository _repository;

    public Controller()
    {
        _repository = new CarModelRepository();
    }

    public void DoSomething()
    {
        //use repository here
    }
}

查看此类的构造函数,您可以看到它通过执行

创建了自己的依赖项。
_repository = new CarModelRepository();

在这种情况下,Controller包含对具体CarModelRepository的依赖。

如果要应用依赖关系反转原理,则将在此处删除实例化,并注入作为抽象依赖。在这种情况下,控制器将如下所示:

class Controller
{
    private ICarModelRepository _repository;

    public Controller(ICarModelRepository repository)
    {
        _repository = repository;
    }

    public void DoSomething()
    {
        //use repository here
    }
}

请注意,现在存储库是ICarModelRepository,它是接口,不再是具体类型,并且Controller不会创建它(作为具体依赖项),但会将其作为抽象依赖项接收(界面)。

这是Dependency Inversion原理含义的一个示例,在您的情况下,您没有将依赖关系发送到存储库,而是发送了需要保存的对象。代表应用程序模块的对象是应视为依赖项的事物,例如在存储库中,应将其注入。您的域对象不是要注入的依赖项,因此,可以回答您的问题:

  

存储库实现是否违反DiP原则?

不,不是。