xvd*_*iff 2 c# design-patterns domain-driven-design entity-framework ddd-repositories
今天,我需要设计一个实体,它拥有对它的聚合根的引用.为了确保实体的实例引用与其包含的聚合根相同的聚合根,我做了一些限制,只有聚合根才能创建实体.
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; }
}
Run Code Online (Sandbox Code Playgroud)
突然间,一个关于聚合的一个非常重要的概念击中了我:聚合物并没有神奇地出现在任何地方.没有'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;
}
}
Run Code Online (Sandbox Code Playgroud)
这样,数据库(或例如EF)可以自动生成密钥,也可以在存储库中定义验证规则,如果实体正在被修改(和更新)等也适用.
或者我现在混在一起吗?这更像是服务/工厂的任务吗?
库只是抽象的持久性,虽然它恢复(也许,也许是存储本身并没有恢复)的总根,它不会创造它.存储库的目的不是创建对象.
一个工厂的目的是为了创建对象,当创作并不简单但是工厂使用(如新的MyObject()),它依赖于一些规则,或者你不知道该问哪些具体类型(抽象工厂) .
关于聚合根必须来自某个地方,我不同意.他们没有必要,但从语义的角度来看它是有意义的.我一直做"新的MyAggregate(id)",这不是问题,没有必要按照一些武断的规则强迫事情,只因为有人这么说.如果你有充分的理由(设计,技术),那就去做吧.如果没有,不要让你的生活复杂化.