今天,我需要设计一个实体来保存对其聚合根的引用。为了确保实体的实例引用与其包含的聚合根相同的聚合根,我做了一些限制,只有聚合根才能创建实体。
public class Aggregate {
public int Id { get; }
public IEnumerable<Entities> Entities { get; }
public Entity CreateEntity(params);
}
public class Entity {
public int Id { get; }
public Aggregate Parent { get; }
}
突然间,关于聚合的一个非常重要的概念让我印象深刻:聚合不会神奇地凭空出现。没有“new Aggregate(id);”这样的东西在 DDD 世界中。
那么,现在我要问.. 谁负责创建它们?我知道有工厂等,但考虑到聚合的身份可能是由数据库生成的代理项,存储库负责聚合创建不是很合理吗?
public class MyAggregate {
public int Id { get; private set; }
protected MyAggregate() {}
public MyAggregate(int id) {
Id = id;
}
}
public interface IMyAggregateRepository {
MyAggregate Create();
void DeleteById(int id);
void Update(MyAggregate aggregate);
MyAggregate GetById(int id);
// no Add() method on this layer!
}
private class EfMyAggregateRepository : IAggregateRepository {
public EfMyAggregateRepository(DbContext context) {
...
}
public MyAggregate Create() {
var pto = context.Create<MyAggregate>();
context.Set<MyAggregate>().Attach(pto);
return pto;
}
}
那样的话,数据库(或例如 EF)可能会自动生成一个 key ,也许在存储库中定义验证规则也适用,如果实体正在被修改(和更新)等等。
还是我现在把事情搞混了?这更多是服务/工厂的任务吗?
最佳答案
存储库只是对持久性进行抽象,并且在恢复(也许存储本身进行恢复)聚合根时,它不会创建它。存储库的目的不是创建对象。
工厂的目的是创建对象,但是当创建不直接时使用工厂(如 new myobject() )并且它取决于某些规则或者您不知道要请求哪种具体类型(抽象工厂)。
关于聚合根必须来自某个地方,我不同意。它们不是 必须 ,但如果从语义的角度来看有意义,它是首选。我一直在做“new MyAggregate(id)”,这不是问题,没有必要根据一些任意规则强制执行,只是因为有人这么说。如果你有充分的理由(设计、技术),那就去做吧。如果没有,请不要让您的生活复杂化。
关于c# - 存储库作为工厂?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27841760/