Какой уровень я должен реализовать кэширование данных поиска из базы данных в приложении DDD? - PullRequest
2 голосов
/ 09 ноября 2011

Я разрабатываю службу WCF с использованием DDD. У меня есть слой службы домена, который вызывает хранилище для создания объектов домена. Хранилище реализовано с использованием ADO.Net, а не ORM. Данные поступают из БД с использованием Stored Procs. При создании объекта, скажем, Address, SP возвращает id для состояния. SP не будет соединять таблицу адресов с таблицей состояний. Состояние представлено классом объекта значения State, который имеет свойства id, abbr и name. Список объектов состояния можно кэшировать (используя system.runtime.caching.memorycache), когда приложение запускается, поскольку оно является энергонезависимым. В общем, у меня есть LookupDataRepository, который может получить все такие данные поиска из таблиц. Теперь AddressRepository должен заполнить свойство State адреса из идентификатора состояния.
псевдокод:

class AddressRepository : IAddressRepository
{
    Address GetAddressById(int id)
    {
        // call sp and map from data reader
        Address addr = new Address(id);
        addr.Line = rdr.GetString(1);
        addr.State = // what to do ?, ideally LookupCache.GetState(rdr.GetInt32(2))
    }
}

class State
{
    public int Id;
    public string Abbr;
    public string Name;
    enum StateId {VIC, NSW, WA, SA};
    public static State Victoria = // what to do, ideally LookupCache.GetState(StateId.VIC)
}

// then somewhere in address domain model
if(currentState = State.Victroia)
{
    // specific logic for Victoria
}

У меня вопрос, в какой слой поместить этот кеш? Сервис, Репозиторий, отдельная сборка доступна для всех слоев.

Ответы [ 2 ]

8 голосов
/ 11 ноября 2011

Где поставить кеш? Это зависит. Если ваш сценарий будет заключаться в том, что вы добавляете свой IAddressRepository в несколько сервисов приложений (я полагаю, вы называете их доменными службами), результатом будет:

  • Кэширование на уровне хранилища приведет к тому, что все сервисы получат выгоду (Плюсы).
  • Кэширование на уровне репозитория приведет к тому, что все службы должны использовать кеш (минусы).
  • Кэширование на уровне сервиса будет кэшироваться только для тех клиентов / сервисов, которые используют этот конкретный сервис и методы (Плюсы / Минусы?)
  • Если у вас есть управление транзакциями на уровне сервиса, вам нужно быть осторожным при применении кэширования на уровне репозитория. Иногда операция чтения может попасть в кэш, и транзакция не может проверить, что считанные данные, для которых вы предполагаете выполнить операцию записи, не изменены.

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

Я действительно рекомендую написать оболочку кеша, такую ​​как

public class CacheManager : ICacheManager
{
 public Address Address
        {
            get { }
            set { }
        }
}

Содержит статическую ссылку на System.Runtime.Caching.MemoryCache.Default.

Это делает ваш тип кэширования безопасным, а приведение в действие выполняется только внутри оболочки. Вы также можете выполнить модульное тестирование своих сервисов с помощью Mocked ICacheManager.

Более продвинутый подход заключается в том, чтобы сделать это с помощью Аспектно-ориентированного программирования и декораторов / перехватчиков. У вас есть масса полезной информации здесь, на StackOverFlow https://stackoverflow.com/search?q=AOP+caching

0 голосов
/ 18 января 2019

По моему мнению и исходя из моего опыта, приведет ли кеширование как хранилище к дублирующему коду, усложнит домен и все события должны быть кэшированы?Поскольку интерфейс IRepository будет реализован ... Поэтому я выбрал инфраструктурный сервис, давайте кешировать только то, что нужно в нашем приложении.Он также доступен для всех других служб, которые хотят его использовать.

...