我是否误解了存储库模式的意图?
我会说“是的”,但要知道我和我共事过的每个人都出于同样的原因问过同样的事情…… “你不是在思考 4 维,马蒂”。
让我们稍微简化一下,并首先坚持使用构造函数而不是 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
意志即可。
如果我想延迟加载成员编辑器,项目是否也需要对存储库的引用?
现在,关于如何按需重新填充编辑器的项目,您有几个选择,具体取决于您的目标。直接存储库说你想要:
IEnumerable<Project> list = projectRepository.GetAllProjects()
.Where(x => x.editorId == e.Id);
但是放在哪里呢?不是在 Project 或 Editor 中,你是对的,否则他们将不得不访问存储库,这是不好的。上面的代码片段是松耦合的,但不能单独重用。您刚刚达到了存储库模式的极限。
接下来是您的应用程序的适配器层,具有存储库的共享源StaticServiceWrapper
(流利地使用所有必要的存储库。我没有在生产系统中完全这样做过,但给你看一个简洁的例子:
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 IEnumerable<Project> GetProjects(this Editor e)
{
return StaticServiceWrapper.projectRep.GetAllProjects()
.Where(x => x.editorId == e.Id);
}
// many to many, harder
public static IEnumerable<Editor> 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、Add、Update、Remove Object Repository 完成后,您就必须不理会关联,然后将对象/层层次结构向上移动到有趣的部分,例如适配器和缓存以及业务逻辑(“哦,我的!”)。