我有一个具有编辑器和项目概念的域模型.
编辑拥有许多项目,项目不仅有编辑所有者,还有许多编辑成员.因此,编辑还有一些"加入"项目.
我正在采用DDD方法对此进行建模并使用Repository模式进行持久化.但是,我还没有足够好地确定模式,以确定我应该如何做到这一点.
我正在假设编辑器和项目可能在同一个聚合中,其中根是编辑器.因此,我可以获得一个编辑器,然后枚举其项目,并可以从那里枚举项目的成员编辑.
但是,如果我只被允许从我的存储库中检索编辑器,这是不是意味着当我获得拥有它们的编辑器时我必须从存储库加载所有项目?如果我想延迟加载成员编辑器,项目还需要对存储库的引用?
或者,如果我拆分聚合并拥有一个编辑器存储库和一个项目存储库,那么我应该如何处理两者之间的事务,例如将新项目添加到编辑器中?例如:
Editor e = new Editor("Editor Name"); editorRepository.Add(e); Project p = e.CreateProject("Project Name"); projectRepository.Add(p); // These two lines editorRepository.Save(e); // should be atomic
我是否误解了Repository模式的意图?
我是否误解了Repository模式的意图?
我要说"是的",但要知道我和我曾经合作的每个人都出于同样的原因问过同样的事情...... "你不是在想第四维,马蒂".
让我们稍微简化一下,先使用构造函数而不是Create方法:
Editor e = new Editor("Editor Name"); e = editorRepository.Add(e); Project p = new Project("Project Name", e); p = projectRepository.Add(p);
在下面,您的项目存储库始终将有效的所有者(p.EditorId
)存储到项目数据中,然后重新填充编辑器的项目,它将存在.这就是将所有必需属性放入构造函数中的好习惯.如果你不想传递整个对象,只需e.Id
要做.
如果我想延迟加载成员编辑器,项目还需要对存储库的引用?
现在,关于如何根据需要重新填充编辑器的项目,您可以根据自己的需求选择几个选项.Straight Repository说你想要:
IEnumerablelist = projectRepository.GetAllProjects() .Where(x => x.editorId == e.Id);
但是把它放在哪里?不在Project或Editor中,你是对的,或者他们必须访问存储库,这是不好的.上面的代码片段松散耦合,但不能自行重复使用.你刚刚达到了Repository Pattern的极限.
接下来是适用于您的应用程序的适配器层,具有共享的存储库源(StaticServiceWrapper
)和某种EditorAdapter对象(或者Aggregate或者您称之为的任何对象),或者现在您可以混合使用可以与任何和所有必要的知识库都很流利.我没有在生产系统中这样做,但为了向您展示一个简洁的例子:
public static class Aggregators { // one to one, easy public static Editor GetOwner(this Project p) { return StaticServiceWrapper.editorRep.GetEditorById(p.editorId); } // one to many, medium public static IEnumerableGetProjects(this Editor e) { return StaticServiceWrapper.projectRep.GetAllProjects() .Where(x => x.editorId == e.Id); } // many to many, harder public static IEnumerable GetMembers(this Project p) { var list = StaticServiceWrapper.projectMemberMap.GetAllMemberMaps() .Where(x => x.projectId == p.projectId); foreach ( var item in list ) yield return StaticServiceWrapper.editorRep.GetEditorById(item.editorId); } }
基本上,一旦完成GetAll,GetById,添加,更新,删除对象存储库,就必须单独保留关联,并将对象/层层次结构移动到有用的部分,如适配器和缓存以及业务逻辑("哦,我的!").