DDD, хранилища и ролевые интерфейсы - PullRequest
1 голос
/ 19 мая 2011

Буду очень признателен за мнение людей по поводу проблемы с дизайном

У меня есть модель, в которой либо «Лицо», либо «Бизнес» может быть поставщиком определенной «Услуги». Пример определения класса показан ниже:

IProvider
Guid Id

Персона: IProvider
Guid Id
строка Имя
строка Фамилия

Бизнес: IProvider
Guid Id
строка Имя

Услуги
Guid Id
IProvider провайдер

Поэтому я создал соответствующие концепции в своем домене: «Персона», «Бизнес», «IProvider» и «Сервис». Я борюсь за то, на каких объектах создавать репозитории. В этом контексте «Сервис» является совокупным корнем и поэтому имеет свой собственный репозиторий. «Бизнес» - это также совокупный корень в моем контексте, так как он будет иметь значение, даже если он не является поставщиком. «Персона» будет создана в системе только в том случае, если она «является провайдером».

Буду ли я создавать репозиторий на роль IProvider, который будет возвращать мне экземпляры «Персона» и «Бизнес»; Мои проблемы с этим заключаются в том, что код может быстро стать довольно сложным, поскольку любая реализация должна будет просматривать несколько таблиц и т. д., чтобы вернуть все различные типы IProvider. Такой подход потребовал бы создания репозиториев для «Персона» и «Бизнес» и добавления их в репозиторий «IProvider» для обеспечения требуемой функциональности, т.е.

public class ProviderRepository : IProviderRepoistory
{
    public IBusinessRepository businessRepository {get; set; }
    public IPersonRepository personRepository {get; set; }

    public IProvider FindById(Guid Id){
        IProvider entity = businessRepository.FindById(Id);

        if(entity == null)
            entity = personRepository.FindById(Id);

        return entity;
    }
}

Другим подходом было бы создание репозиториев для сущностей «Персона» и «Бизнес», которые реализуют интерфейс «IProvider», что делает их доступными для участия в этой роли. * 1050 т.е. *

public class PersonRepository : IPersonRepository, IProviderRepository
{
    private ISession session;        

    public Person FindById(Guid Id){
        return session.Query<Person>().FirstOrDefault<Person>(x => x.Id == Id);
    }

    public IProvider FindById(Guid Id){
        return session.Query<Person>().FirstOrDefault<Person>(x => x.Id == Id && x.IsProvider == true);
    }
}

Затем я бы использовал механизм (т.е. контейнер IoC), чтобы выбрать правильную конкретную реализацию IProviderRepository, когда это необходимо. Например, если я имею дело с поставщиком, которого я знаю как человека, я могу получить реализацию PersonRepository.

Другим вариантом будет не внедрять какие-либо репозитории IProvider, а просто придерживаться репозиториев «Person» и «Business» и использовать их в соответствии с требованиями на уровне обслуживания?

1 Ответ

0 голосов
/ 19 мая 2011

Я думаю, что вы слишком много думаете об этом, и вы пытаетесь оптимизировать слишком рано.

Из всего, что вы здесь сказали, мне кажется, что Человек и Бизнес оба являются сущностями, но неявляется совокупностью (хотя, очевидно, я мог бы что-то упустить в ваших дискуссиях с экспертами в области).Мне кажется, что поставщик является агрегатом.

Когда вы создаете репозиторий ProviderRepository, вам не нужно внедрять репозитории для предприятий и лиц, b / c, если они не являются агрегатами, они не должныимеют свои собственные репозитории.Вместо этого ProviderRepository должен использовать Session напрямую, чтобы выбрать то, что ему нужно, из любой схемы БД, которую вы придумали для составления рассматриваемых сущностей для данного запроса.Если вы правильно отобразите наследование, вы можете выполнять запросы к базовому классу или интерфейсу.

...