C# 不';清洁体系结构中的t存储库模式违反依赖倒置原则?

C# 不';清洁体系结构中的t存储库模式违反依赖倒置原则?,c#,oop,design-patterns,.net-core,clean-architecture,C#,Oop,Design Patterns,.net Core,Clean Architecture,从我所阅读和看到的内容来看,clean architecture假设您有一些对持久性一无所知的实体,尽管它们位于同一层,但可能有一个接口,其目的是作为一个关于如何读取/更新/删除实体的契约 //项目核心 公共级CarModel { 公共字符串名称{get;set;} public void SomeImportantBehavior{} } 公共接口ICarModelRepository { CarModel FindByName(字符串名称); CarModel Add(CarModel Ca

从我所阅读和看到的内容来看,clean architecture假设您有一些对持久性一无所知的实体,尽管它们位于同一层,但可能有一个接口,其目的是作为一个关于如何读取/更新/删除实体的契约

//项目核心
公共级CarModel
{
公共字符串名称{get;set;}
public void SomeImportantBehavior{}
}
公共接口ICarModelRepository
{
CarModel FindByName(字符串名称);
CarModel Add(CarModel CarModel);
}
同时,另一层将容纳接口的实现:

//项目基础结构或持久性
公共类CarModelRepository:ICarModelRepository
{
公共CarModel FindByName(字符串名称)
{
returnnewcarmodel{Name=Name};//这里的实现并不重要
}
公共CarModel Add(CarModel CarModel){
//不知怎的,在这里坚持下去
返回carModel;
}
}
所以我有一个问题:存储库实现是否违反了DiP原则?因为它不仅依赖于抽象,还依赖于具体的实现(在本例中是
CarModel

另一个例子是


p.S.
CarModel
是一个具有行为的域模型。

您缺少了一点依赖倒置原则。该原理应反映不同模块之间的解耦。换句话说,您不应该在需要的地方实例化对象,而是将它们作为参数接收。这是我们的基本原则

为了清楚起见,我们假设您有一个类
控制器
,它使用您的
存储库
。如果没有DI,一开始会是这样:

class Controller
{
    private CarModelRepository _repository;

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

    public void DoSomething()
    {
        //use repository here
    }
}
class Controller
{
    private ICarModelRepository _repository;

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

    public void DoSomething()
    {
        //use repository here
    }
}
查看这个类的构造函数,您可以看到它通过

_repository = new CarModelRepository();
在这种情况下,
控制器
包含对具体的
CarModelRepository
的依赖关系

如果您想应用依赖项反转原则,那么您将删除那里的实例化,并将依赖项作为抽象注入。在这种情况下,控制器将如下所示:

class Controller
{
    private CarModelRepository _repository;

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

    public void DoSomething()
    {
        //use repository here
    }
}
class Controller
{
    private ICarModelRepository _repository;

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

    public void DoSomething()
    {
        //use repository here
    }
}
请注意,现在存储库是
ICarModelRepository
,它是接口,不再是具体类型,
Controller
不创建它(作为具体依赖项),而是作为抽象依赖项(接口)接收它

这是一个依赖项反转原则的示例,在您的例子中,您并没有将依赖项发送到存储库,而是发送一个需要保存的对象。表示应用程序模块的对象是作为存储库的情况而应视为依赖项并注入它们的事物。您的域对象不是要注入的依赖项,因此,回答您的问题:

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


不,它没有。

您缺少了一点依赖倒置原则。该原理应反映不同模块之间的解耦。换句话说,您不应该在需要的地方实例化对象,而是将它们作为参数接收。这是我们的基本原则

为了清楚起见,我们假设您有一个类
控制器
,它使用您的
存储库
。如果没有DI,一开始会是这样:

class Controller
{
    private CarModelRepository _repository;

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

    public void DoSomething()
    {
        //use repository here
    }
}
class Controller
{
    private ICarModelRepository _repository;

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

    public void DoSomething()
    {
        //use repository here
    }
}
查看这个类的构造函数,您可以看到它通过

_repository = new CarModelRepository();
在这种情况下,
控制器
包含对具体的
CarModelRepository
的依赖关系

如果您想应用依赖项反转原则,那么您将删除那里的实例化,并将依赖项作为抽象注入。在这种情况下,控制器将如下所示:

class Controller
{
    private CarModelRepository _repository;

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

    public void DoSomething()
    {
        //use repository here
    }
}
class Controller
{
    private ICarModelRepository _repository;

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

    public void DoSomething()
    {
        //use repository here
    }
}
请注意,现在存储库是
ICarModelRepository
,它是接口,不再是具体类型,
Controller
不创建它(作为具体依赖项),而是作为抽象依赖项(接口)接收它

这是一个依赖项反转原则的示例,在您的例子中,您并没有将依赖项发送到存储库,而是发送一个需要保存的对象。表示应用程序模块的对象是作为存储库的情况而应视为依赖项并注入它们的事物。您的域对象不是要注入的依赖项,因此,回答您的问题:

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


不,它不是。

我想说,从你的例子来看,
CarModel
是一个没有行为的简单数据结构,“具体”和“抽象”的概念不适用于它。我投票结束这个问题,因为它似乎更适合行为所需的抽象,以前的评论没有正确的想法:抽象原则适用于对象,这些对象在概念上与数据结构分离。更深入的答案可以在@jaco0646中找到,这是最简单的示例-我现在用行为更新了一个实体。这些例子我在互联网上到处都能看到,我只是想知道这是正确的,还是我们缺乏一些抽象?如果答案是肯定的,那么抽象应该如何实现我会说,从你的例子来看,
CarModel
是一个没有行为的简单数据结构,“具体”和“抽象”的概念不适用于它。我投票结束这个问题,因为它似乎更适合行为所需的抽象,以前的评论没有正确的想法:抽象原则适用于对象,这些对象在概念上与数据结构分离。可以找到更深入的答案