Иногда можно использовать шаблон локатора службы в доменном классе? - PullRequest
1 голос
/ 21 марта 2012

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

Пока что все зависимости интерфейса в моем домене разрешаются с помощью DI из исполняемой сборки, которая на данный момент является проектом .NET MVC3 (+ контейнер Unity IoC). Однако я столкнулся со сценарием, где я думаю, что сервисный локатор может быть лучшим выбором.

В домене есть объект, который хранит (кэширует) контент из URL. В частности, он хранит XML SAML2 EntityDescriptor из URL-адреса метаданных. У меня есть интерфейс IConsumeHttp с одним методом:

public interface IConsumeHttp
{
    string Get(string url);
}

Текущая реализация использует статический класс WebRequest в System.Net:

.
public class WebRequestHttpConsumer : IConsumeHttp
{
    public string Get(string url)
    {
        string content = null;
        var request = WebRequest.Create(url);
        var response = request.GetResponse();
        var stream = response.GetResponseStream();
        if (stream != null)
        {
            var reader = new StreamReader(stream);
            content = reader.ReadToEnd();
            reader.Close();
            stream.Close();
        }
        response.Close();
        return content;
    }
}

Сущность, которая кэширует содержимое XML, существует как некорневая в гораздо большем совокупности сущностей. Для остальной части совокупности я реализую довольно большой шаблон Facade, который является публичной конечной точкой для контроллеров MVC. Я мог бы добавить зависимость IConsumeHttp в конструктор фасада следующим образом:

public AnAggregateFacade(IDataContext dataContext, IConsumeHttp httpClient)
{
    ...

Проблема, с которой я сталкиваюсь, заключается в том, что только один метод на фасаде имеет зависимость от этого интерфейса, поэтому глупо внедрять его для всего фасада. Создание объекта класса WebRequestHttpConsumer не должно добавлять много накладных расходов, но домен не знает об этом.

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

Мой вопрос: это плохая идея? Мне кажется, что ответственность за обеспечение надлежащего кэширования метаданных XML должна лежать на домене. Домен делает это периодически как часть других связанных операций (таких как получение метаданных для запросов и ответов SAML Authn, обновление SAML EntityID или URL-адреса метаданных и т. Д.). Или я просто слишком переживаю из-за этого?

Ответы [ 2 ]

0 голосов
/ 27 марта 2012

В своем комментарии к @ ian31 вы упомянули: «Похоже, заставить контроллер убедиться, что в домене правильный XML слишком гранулированный, что накладывает на клиента слишком большую ответственность». По этой причине я бы предпочел, чтобы контроллер запрашивал у своего сервиса / репозитория (который может реализовать уровень кэширования) правильный и текущий XML. Для меня эта обязанность очень важна для субъекта домена.

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

0 голосов
/ 22 марта 2012

Мне кажется, что ответственность за домен должна лежать на убедитесь, что метаданные XML должным образом кэшированы

Я не уверен в этом, если только ваш домен не занимается манипулированием метаданными, запросами http и так далее. Для «обычного» приложения с нетехнической областью я бы предпочел решить проблемы с кэшированием на уровне инфраструктуры / технических служб.

Проблема, с которой я сталкиваюсь, заключается в том, что только один метод на фасаде имеет зависимость от этого интерфейса, поэтому глупо вводить его для весь фасад

Очевидно, что Фасады обычно не очень хорошо поддаются внедрению в конструктор, поскольку они, как правило, указывают на множество зависимостей. Вы можете рассмотреть другие типы инъекций или, как вы указали, использовать локатор. Но я лично хотел бы спросить себя, действительно ли подходит Фасад, и подумать об использовании более мелких объектов вместо одного и того же большого интерфейса во всех моих контроллерах. Это позволило бы повысить модульность и оперативную инъекцию, а не раздувать массивный объект заранее.

Но это может быть просто потому, что я не большой фанат Фасада;)

...