Попытка выяснить, как лучше всего обработать следующий сценарий:
Примите 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, должен знать о фабрике и реализовать его, который не действительно очевиден).
Существует ли лучше/больше поддающийся обнаружению способ, которым я отсутствую?
Прелесть слабой связи в том, что мы можем постоянно скрывать предыдущие детали .
С точки зрения потребителя 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);
Шаблон Factory - это хорошо известный, документированный и используемый метод. Если вас беспокоит, что другие разработчики не в курсе, поместите ссылку на страницу заводских шаблонов википедии в документации (xml) в коде.
Также убедитесь, что вы называете свои фабрики последовательно - похоже, что Microsoft нравится суффикс Provider.