Внедрение зависимости и фабрика

Попытка выяснить, как лучше всего обработать следующий сценарий:

Примите a RequestContext класс, который имеет зависимость к внешнему сервису, такому как:

public class RequestContext : IRequestContext
{
    private readonly ServiceFactory<IWeatherService> _weatherService;

    public RequestContext(ServiceFactory<IWeatherService> weatherService, UserLocation location, string query)
    {
       _weatherService = weatherService;
       ...

Какая зависимость должна я требовать в классе, который в конечном счете инстанцирует RequestContext? Это могло быть ServiceFactory<IWeatherService>, но это не кажется правильным, или я мог создать IRequestContextFactory для него вроде:

public class RequestContextFactory : IRequestContextFactory
{
    private readonly ServiceFactory<IWeatherService> _weatherService;

    public RequestContextFactory(ServiceFactory<IWeatherService> weatherService)
    {
        _weatherService = weatherService;
    }

    public RequestContext Create(UserLocation location, string query)
    {
        return new RequestContext(_weatherService, location, query);
    }
}

И затем передача IRequestContextFactory посредством инжекции конструктора.

Это походит на хороший способ сделать это, но проблема с этим подходом состоит в том, что я думаю, что это препятствует discoverability (devs, должен знать о фабрике и реализовать его, который не действительно очевиден).

Существует ли лучше/больше поддающийся обнаружению способ, которым я отсутствую?

6
задан andreialecu 10 June 2010 в 12:15
поделиться

2 ответа

Прелесть слабой связи в том, что мы можем постоянно скрывать предыдущие детали .

С точки зрения потребителя IRequestContext существование RequestContext и его зависимостей является чисто деталью реализации . Из-за принципа подстановки Лискова , потребитель должен иметь дело только с IRequestContext:

public class MyClass
{
    private readonly IRequestContext reqCtx;

    public MyClass(IRequestContext reqCtx)
    {
        if (reqCtx == null)
        {
            throw new ArgumentNullException("reqCtx");
        }

        this.reqCtx = reqCtx;
    }

    // Implement using this.reqCtx...
}

Только в корне композиции приложения вам нужно, наконец, связать все вместе. Вот набросок подхода DI для бедняков:

ServiceFactory<IWeatherService> weatherService =
    new ServiceFactory<IWeatherService>();
UserLocation location = new UserLocation;
string query = "foo";

IRequestContext reqCtx = new RequestContext(weatherService, location, query);

var mc = new MyClass(reqCtx);
5
ответ дан 17 December 2019 в 04:42
поделиться

Шаблон Factory - это хорошо известный, документированный и используемый метод. Если вас беспокоит, что другие разработчики не в курсе, поместите ссылку на страницу заводских шаблонов википедии в документации (xml) в коде.

Также убедитесь, что вы называете свои фабрики последовательно - похоже, что Microsoft нравится суффикс Provider.

0
ответ дан 17 December 2019 в 04:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: