根据我所看到的内容,干净的体系结构假设您有一些对持久性一无所知的实体,尽管在它们驻留的同一层中可能存在一个接口,该接口的目的是就实体的方式达成约定读取/更新/删除。
// 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
是具有行为的域模型。
答案 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原则?
不,不是。