干净架构中的存储库模式是否违反了依赖倒置原则?
Doesn't repository pattern in clean architecture violate Dependency inversion principle?
根据我所读和看到的内容,干净的架构假定您有一些实体,它们对持久性一无所知,尽管在它们所在的同一层可能有一个接口,其目的是成为关于实体如何运作的契约应该是 read/updated/deleted.
// 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
是一个具有行为的领域模型。
你有点遗漏了依赖倒置原则的要点。这个原则应该反映不同模块之间的解耦。换句话说,您不应该在需要的地方实例化您的对象,而是将它们作为参数接收。这是 dependency injection.
的基本原则
为了清楚起见,我们假设您有一个 class Controller
使用您的 Repository
。没有 DI,起初它看起来像这样:
class Controller
{
private CarModelRepository _repository;
public Controller()
{
_repository = new CarModelRepository();
}
public void DoSomething()
{
//use repository here
}
}
查看此 class 的构造函数,您可以看到它通过执行
创建了自己的依赖项
_repository = new CarModelRepository();
在这种情况下,Controller
包含对具体 CarModelRepository
的依赖。
如果你想应用依赖倒置原则,那么你将删除那里的实例化并注入依赖作为抽象。在这种情况下,控制器将如下所示:
class Controller
{
private ICarModelRepository _repository;
public Controller(ICarModelRepository repository)
{
_repository = repository;
}
public void DoSomething()
{
//use repository here
}
}
请注意,现在存储库是 ICarModelRepository
,它是接口,不再是具体类型,Controller
不会创建它(作为具体依赖项),但它会接收它作为一个抽象依赖(接口)。
这是依赖倒置原则意味着什么的示例,在您的情况下,您没有向存储库发送依赖项,而是发送需要保存的对象。代表应用程序模块的对象是您应该视为依赖项并注入它们的东西,就像存储库的情况一样。您的域对象不是要注入的依赖项,所以回答您的问题:
doesn't repository implementation violate the DiP principle?
不,不是。
根据我所读和看到的内容,干净的架构假定您有一些实体,它们对持久性一无所知,尽管在它们所在的同一层可能有一个接口,其目的是成为关于实体如何运作的契约应该是 read/updated/deleted.
// 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
是一个具有行为的领域模型。
你有点遗漏了依赖倒置原则的要点。这个原则应该反映不同模块之间的解耦。换句话说,您不应该在需要的地方实例化您的对象,而是将它们作为参数接收。这是 dependency injection.
的基本原则为了清楚起见,我们假设您有一个 class Controller
使用您的 Repository
。没有 DI,起初它看起来像这样:
class Controller
{
private CarModelRepository _repository;
public Controller()
{
_repository = new CarModelRepository();
}
public void DoSomething()
{
//use repository here
}
}
查看此 class 的构造函数,您可以看到它通过执行
创建了自己的依赖项_repository = new CarModelRepository();
在这种情况下,Controller
包含对具体 CarModelRepository
的依赖。
如果你想应用依赖倒置原则,那么你将删除那里的实例化并注入依赖作为抽象。在这种情况下,控制器将如下所示:
class Controller
{
private ICarModelRepository _repository;
public Controller(ICarModelRepository repository)
{
_repository = repository;
}
public void DoSomething()
{
//use repository here
}
}
请注意,现在存储库是 ICarModelRepository
,它是接口,不再是具体类型,Controller
不会创建它(作为具体依赖项),但它会接收它作为一个抽象依赖(接口)。
这是依赖倒置原则意味着什么的示例,在您的情况下,您没有向存储库发送依赖项,而是发送需要保存的对象。代表应用程序模块的对象是您应该视为依赖项并注入它们的东西,就像存储库的情况一样。您的域对象不是要注入的依赖项,所以回答您的问题:
doesn't repository implementation violate the DiP principle?
不,不是。