背景
根据我自己的理解,我正在尝试为一个简单的场景创建一个分层架构。我有一个简单的域类 Car。
public class Car {
public string Make;
public string Model;
public int Year;
public Accelerate() { }
public Decelerate() { }
}
我想创建一个 Car 的新实例,从数据库中填充其值。 这就是我卡住的地方。
我认为在 Persistence 层(称为 CarRepository)中应该有另一个类,它将完成从基于 CarID 的数据库中检索这些值的繁琐工作。
我希望在运行时将这个 CarRepository 依赖注入到 Car 域类中,以允许不同的实现(例如用于单元测试的假货)。
因此,我考虑将其添加到 Car 类中:
public class Car() {
private ICarRespository _carRepository;
public Car(ICarRepository carRepository) {
_carRespository = carRepository;
}
public void Find(int carId) {
var car = _carRepository.FindById(carId);
this.Make = car.Make;
this.Model = car.Model;
// etc.
}
// other properties and methods here
}
我会将 ICarRepository 定义为:
public interface ICarRepository {
DtoCar FindById(int carId);
}
public class DtoCar {
public string Make;
public string Model;
public int Year;
}
假设我正在使用“穷人的依赖注入”并允许聚合根根据项目类型(生产代码与单元测试)传递正确的具体 CarRespository。显然我在这里选择使用构造函数注入。
问题
(1) 这个解决方案感觉不对。当我创建一辆新车时,我觉得它应该在此时初始化并填充其所有属性。但是,只有在我调用 Find() 方法之后,它才能真正成为一辆有效的汽车。如果我没有将有效的 CarID 传递给 Find,会发生什么?那么 Car 对象永远不会是一个有效的对象!这不应该打扰我吗?有没有更好的办法?
(2) 我正在使用构造函数注入来传递存储库依赖项……我也可以传递 CarID 以在构造函数中找到此处……然后我可以消除 Find() 方法吗?所以:
public Car(ICarRepository carRepository, int carId) {
_carRespository = carRepository;
var car = _carRepository.FindById(carId);
this.Make = car.Make;
this.Model = car.Model;
// etc.
}
...我从来没有见过这样的做法,所以我很犹豫要不要使用它。这样做可以吗?
(3)我在这里缺少一些创造模式吗?这是一个简单的场景……我不相信像 Factory、Singleton 或 Prototype 这样的东西在这里适用(我可能弄错了)。那些感觉沉重和专业。这个场景——来自数据库的一个简单的域对象——看起来很基本,必须有一些指导。