Репозиторий и сервисный вопрос - PullRequest
3 голосов
/ 22 февраля 2010

Мы пытаемся найти наилучшую практику при использовании DDD, и мы ведем некоторые дискуссии о том, что является наиболее разумным или является «правильным путем».

Примечание. Весь код является псевдокодом.

Conceder следующее:

public interface IDomainEntityAService
{
    void CreateMyObject(DomainEntityA myobject);
    DomainEntityA RetrieveDomainEntityA(long someId);
    //Other operations that handle the business logic dealing with MyObject
}

У нас также есть другая служба, которая использует части IDomainEntityAService для удовлетворения особых потребностей.

public interface IDomainEntityBService
{
    DomainEntityB GetDomainEntityB();
}

где OtherInformation содержит следующее:

public class DomainEntityB
{
    public string Name { get; set; }
    public IList<DomainEntityA> DomainEntityAList { get; set; }
}

Теперь приходит наш вопрос. Мы планируем использовать хранилище для сохранения OtherInformation, как показано ниже:

public interface IDomainEntityBRepository
{
    void Add(DomainEntityB information);
    DomainEntityB Get(long someId);
}

Поскольку мы хотим, чтобы все было как можно более СУХИМ, в идеале мы хотели бы повторно использовать логику IDomainEntityAService для получения списка DomainEntityAList для DomainEntityB. Какой из них имеет наибольшее значение?

A) иметь ссылку на IDomainEntityAService в IDomainEntityBRepository например,

public class SqlDomainEntityBRepository : IDomainEntityBRepository
{

    public SqlDomainEntityBRepository(IDomainEntityAService domainEntityAService, Database database)
    {

    }

    public void Add(DomainEntityB information)
    {
        //save DomainEntityB to SQL
    }
    public DomainEntityB Get(long someId)
    {
        //Get OtherInformation.Name from SQL
        //use domainEntityAService.Get() to populate the list of DomainEntityAList
        //return DomainEntityB
    }
}

B) IDomainEntityBRepository обрабатывает только содержимое SQL, и мы используем служебный уровень для IHaveOtherInformation, чтобы заполнить список MyObjects

public class DomainEntityBService : IDomainEntityBService
{
    public DomainEntityBService(IDomainEntityAService domainEntityAService, IDomainEntityBRepository repo)
    {
    }
    public DomainEntityB GetDomainEntityB()
    {
        var domainEntityB = _repo.Get(someId);
        domainEntityB.DomainEntityAList = _domainEntityAService.GetAll(someId);
        return domainEntityB;
    }
}

C) Мы создаем специальный объект DAL для OtherInformation и используем уровень обслуживания для создания экземпляра OtherInformation

public class DomainEntityBDAL
{
    public string Name { get; set; }
    public IList<int> DomainEntityAListIds { get; set; }
}

Тогда у нас будет хранилище для извлечения OtherInformationDAL, и тогда код будет выглядеть следующим образом:

public class DomainEntityBService : IDomainEntityBService
{

    public DomainEntityBService(IDomainEntityAService domainEntityAService, IDomainEntityBRepository repo)
    {
    }
    public DomainEntityB GetDomainEntityB()
    {

        var domainEntityBDAL = _repo.Get(someId);
        DomainEntityB result = new DomainEntityB() { Name = domainEntityBDAL.Name };
        foreach (var id in domainEntityBDAL.DomainEntityAListIds)
        {
            result.DomainEntityAList.Add(_domainEntityAService.Get(id));
        }
        return result;
    }
}

D) Вау, мы совсем не в себе, сделайте это вместо этого !!!

Надеюсь, это имеет смысл, и спасибо за вашу помощь.

Редактировать заметки:

Возможно, английское описание поможет лучше описать мой вопрос. У нас есть DomainEntityA, который является совокупным корнем. Существует соответствующий сервис для обработки всей логики, которая имеет дело с DomainEntityA.

Теперь у нас также есть DomainEntityB, который является совокупным корнем. Однако DomainEntityB имеет список DomainEntityAs. DomainEntityAs может жить самостоятельно, однако DomainEntityB не может жить без списка DomainEntityAs

Как бы мы загрузили список элементов DomainEntityA в DomainEntityB и сохранили всю логику для DomainEntityA.

Повторно использовать DomainEntityAService в DomainEntityBService?
Создать отдельный DomainEntityARepository в DomainEntityBService?

В настоящее время мы используем EntLib, но ищем больше информации о дизайне, чем о реализации DAL.

Ответы [ 2 ]

0 голосов
/ 23 февраля 2010

Как насчет того, чтобы вместо этого использовать общий интерфейс, который позволяет вам подключать тип? Вот так:

public interface IRepository<T>
{
    T Get(object id);
    void Save(T value);
    void Update(T value);
    void Delete(T value);
    IList<T> GetAll();
}

Какая бы реализация вы ни использовали, она должна иметь возможность читать тип и знать, как он вписывается в базу данных. Это шаблон хранилища в двух словах. Если вы не полностью настроены на Entlib, изучите NHibernate. Я обнаружил, что он хорошо дополняет шаблон репозитория. Я много писал о этой теме в своем блоге, так что вы можете перейти туда, если хотите узнать больше.

0 голосов
/ 22 февраля 2010

Я предполагаю, что вы собираетесь хранить в базе данных.

Ответ на этот вопрос в значительной степени зависит от того, что вы используете в качестве механизма персистентности. Если у вас есть собственное упорство, то C не вариант, потому что вы увидите N + 1 Запросы. B, скорее всего, будет моим первым выбором, потому что он предлагает наибольшее количество повторного использования кода с, надеюсь, не ужасной производительностью.

Сказав, что если вы используете что-то вроде NHibernate, я бы рекомендовал НЕ использовать шаблон хранилища и вместо этого

  • Инкапсуляция сложных запросов в виде объектов (которые затем могут быть проверены модулем).
  • Используйте сеанс напрямую

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...