Я пытаюсь удалить Service Locator из абстрактного базового класса, но я не уверен, чем его заменить. . Вот псевдо-пример того, что у меня есть:
public abstract class MyController : Controller
{
protected IKernel kernel;
public MyController(IKernel kernel) { this.kernel = kernel); }
protected void DoActions(Type[] types)
{
MySpecialResolver resolver = new MySpecialResolver(kernel);
foreach(var type in types)
{
IMyServiceInterface instance = resolver.Get(type);
instance.DoAction();
}
}
}
Проблема с этим заключается в том, что создатель экземпляра производного класса не знает, какие привязки должно иметь ядро, чтобы сохранить ] MySpecialResolver
от генерации исключения.
Это может быть внутренне неразрешимым, потому что я не знаю отсюда, какие типы мне придется разрешать. Производные классы отвечают за создание параметра types
, но они нигде жестко не запрограммированы. (Типы основаны на наличии атрибутов глубоко внутри иерархии композиции производного класса.)
Я пытался исправить это с помощью отложенной загрузки делегатов, но пока я не нашел чистого решения.
Здесь действительно две проблемы. Первая заключается в том, что контейнер IoC передается контроллеру, действуя как локатор службы. Это легко удалить - вы можете перемещать местоположение вверх или вниз по стеку вызовов, используя всевозможные методы.
Второй вопрос является сложным: как вы можете гарантировать, что у контроллера есть необходимые службы, когда требования не соответствуют Выставляется до выполнения. С самого начала должно было быть очевидно: нельзя! Вы всегда будете зависеть либо от состояния локатора службы, либо от содержимого коллекции. В этом конкретном случае никакие возни никогда не решат проблему, описанную в этой статье со статически типизированными зависимостями. Я думаю, что в конечном итоге я передам массив Lazy в конструктор контроллера и выдаю исключение, если требуемая зависимость отсутствует.