MVC: Как разложить интерфейсы репозитория на основе многоуровневой объектной модели - PullRequest
3 голосов
/ 15 февраля 2011

У меня есть многоуровневая цепочка зависимостей в моей объектной модели:

Организация имеет следующие дочерние отношения:

Organization
    .CompetitionGroups
    .CompetitionGroups.Venues
    .CompetitionGroups.Competitions
        .Divisions.Games
        .Divisions.Games.Participants
        .Divisions.Games.Participants.GameSegments
        .Divisions.SubDivisions...
        .Divisions
            .Teams
            .Teams.Players
            .Teams.Participants
            .Teams.Participants.GameSegments
        .VenueDates

Это всего лишь проблеск в объектной модели,но он сфокусирован на сложности отношений и списков.

Чего я не могу получить, так это того, как лучше всего учитывать мои интерфейсы репозитория с учетом требований, предъявляемых к единице работы.

Например, чтобы создать игру, вам понадобится место и два участника.Означает ли это, что GamesController должен требовать IGameRepository, IVenueDateRepository и IParticipant репозиторий?Должны ли они быть свернуты в один репозиторий?

Кроме того, как насчет случаев потребления?Например, чтобы отобразить расписание команды подписчиков, вам понадобятся все участники этой команды, все игры для этого участника и все игровые сегменты для участника.Если они включены в отдельные репозитории, я не могу понять, как вы можете выполнять эффективные запросы.

Значит ли это, что у вас есть репозитории, специально предназначенные для разных случаев?например:

public interface IScheduleRepository {

    public ICollection<Game> GetScheduleForTeam(Team team);

    // More consumption methods
}

public class ScheduleRepositry : IScheduleRepository {

    public ScheduleRepository (ModelContext context) { 
        // Do stuff with context 
    }

    public ICollection<Game> GetScheduleForTeam(Team team) {

         return (
            from p in context.Participants
            where ((p.Game.VenueDate != null) &&
                (p.TeamId == team.Id))
            orderby p.Game.VenueDate.StartTime
            select p.Game).ToList();
    }

    // more consumption methods

}

public interface IGameRepository {

    public void AddGame(Game game);

    // More crud methods
}

// Not showing games repository

public class GamesController : Controller {

    public GamesController (IGameRepository gamesRepo, 
        IVenueDateRepository venueDateRepo,
        IParticipantRepository participantRepo) { 

        // do stuff with repos here 
    }

    [HttpPost]
    public ActionResult AddGame(Game game) {

         // Skipping validation logic
         // this?

         VenueDate = venueDateRepo.Add(game.VenueDate);
         foreach (Participant p in Game.Participants)
         {
             participantRepo.Add(p);
         }

         Game = gamesRepo.AddGame(game);

         // or this?
         // how would the game repo know to persist 
         // the children elements? is that tight coupling?

         Game = gamesRepo.AddGame(game);
    }

    // more consumption methods

}

Мой вопрос заключается в том, что я пока не понимаю, в какой степени факторинг ваших репозиториев имеет смысл на основе модели связанного объекта.Я бы хотел получить здесь совет.

1 Ответ

0 голосов
/ 15 февраля 2011

Вам необходимо определить свои совокупные корни и границы, а затем спроектировать свои хранилища вокруг корней.

В этом разделе есть хорошая (и краткая) глава в book (бесплатно после регистрации)

Что касается выполнения единицы работы, я обычно делаю это функцией уровня обслуживания.Таким образом, контроллер имеет ссылку на службу, а служба управляет согласованием между хранилищем (ями), сущностью (ями), единицей работы и т. Д.

...