В этой ситуации, вероятно, это неизбежно, вы хотите сохранить надежность развязанной реализации, и, таким образом, вы не можете контролировать создание типа, расположение службы - это вариант ...
о, что меня беспокоило с тех пор, как я прочитал ответ на другой вопрос stackoverflow (точный вопрос ускользает от меня сейчас), где пользователь сказал что-то вроде:Если вы звоните в сервисный локатор, вы делаете это неправильно."
Это был человек с высокой репутацией (я думаю, из сотен тысяч), поэтому я склонен думать, что этот человек знает, о чем он говорит. Я использую DI для своих проектов с тех пор, как впервые начал изучать его и то, насколько хорошо оно относится к модульному тестированию, а что нет. Это то, что мне сейчас очень удобно, и ядумать Я знаю, что я делаю.
Тем не менее, во многих местах я использовал Service Locator для разрешения зависимостей в моем проекте. Однажды яркий пример прибывает из моих реализаций ModelBinder.
Пример типичной модели переплета.
public class FileModelBinder : IModelBinder {
public object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext) {
ValueProviderResult value = bindingContext.ValueProvider.GetValue("id");
IDataContext db = Services.Current.GetService<IDataContext>();
return db.Files.SingleOrDefault(i => i.Id == id.AttemptedValue);
}
}
не настоящая реализация - просто быстрый пример
Поскольку реализация ModelBinder требует нового экземпляра, когда Binderпервый запрошено, невозможно использовать Dependency Injection для конструктора для этой конкретной реализации.
Именно так во многих моих классах. Другой пример - процесс истечения срока действия кэша, который запускает метод всякий раз, когда на моем веб-сайте истекает срок действия объекта кэша. Я запускаю кучу вызовов базы данных, а что нет. Там я тоже использую сервисный локатор, чтобы получить необходимую зависимость.
Еще одна проблема, с которой я недавно столкнулся (о которой я написал здесь вопрос), заключалась в том, что для всех моих контроллеров требовался экземпляр IDataContext, для которого я использовал DI - ноодин Метод действия требует другого экземпляра IDataContext. К счастью, на помощь пришла Ninject с именованной зависимостью. Тем не менее, это было похоже на клочок, а не реальное решение.
Мне показалось, что я, по крайней мере, достаточно хорошо понял концепцию разделения проблем, но, похоже, что-то в корне неверно в том, как я понимаю внедрение зависимостей и шаблон локатора служб - и я не знаю, что это такое.
То, как я в настоящее время понимаю это - и это также может быть неправильно - заключается в том, что, по крайней мере, в MVC ControllerFactory ищет конструктор для контроллера и вызывает сам локатор службы, чтобы получить необходимые зависимости, а затем передает их. Однако Я могу понять, что не все классы, а какие нет Фабрики для их создания. Так что мне кажется, что какой-то шаблон локатора сервиса приемлем ... но ...
Когда это не приемлемо?Какой шаблон мне следует искать, когда я должен переосмыслить то, как я использую шаблон сервисного локатора?Моя реализация ModelBinder неверна? Если так, что мне нужно научиться это исправить?В другом вопросе в соответствии с этим одним пользователемМарк Симанн рекомендовал абстрактную фабрику - как это связано?Я думаю, что это так - я не могу придумать ни одного другого вопроса, чтобы помочь моему пониманию, но любая дополнительная информация очень ценится.
Я понимаю, что DI не может быть ответом на все вопросы, и я, возможно, буду зацикливаться на том, как я его реализую, однако, похоже, что он работает так, как я ожидаю, с модульным тестированием, а что нет.
Я не ищу код для исправления моего примера реализации - я стремлюсь учиться, ищу объяснение, чтобы исправить мое ошибочное понимание.
Я бы хотел, чтобы stackoverflow.com имел возможность сохранять черновики вопросов. Я также надеюсь, что тот, кто ответит на этот вопрос, получит соответствующую репутацию за ответ на этот вопрос, так как я думаю, что прошу много. Заранее спасибо.