Я неправильно истолковал намерение шаблона Repository?
Я собираюсь сказать «да», но знайте, что я и все, с кем я работал, спрашивали об одном и том же по одной и той же причине ... «Вы не думаете о 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 или редактора, вы правы, иначе им придется получить доступ к репозиториям, а это бесполезно. Вышеуказанный фрагмент слабо связан, но сам по себе не может использоваться повторно. Вы только что достигли пределов шаблона репозитория.
Далее следует уровень адаптера для вашего приложения с общим источником репозиториев (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 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 завершен, вам нужно оставить ассоциации в покое и перейти вверх по иерархии объектов / слоев к забавным частям, таким как Adapters and Caches и Business Logic. ( «О, боже мой!» ).