2016-10-26 3 views
4

(Запись из памяти)Разрешающая иерархию классов и интерфейсов с Unity

Попытка сделать я в SOL I D. Учитывая

public interface ISettingsReader 
{ 
} 

public interface ISettingsWriter : ISettingsReader 
{ 
} 

public class SettingsManager : ISettingsWriter 
{ 
} 

myContainer.RegisterType<ISettingsWriter, SettingsManager>(); 

почему следующие жалуюсь что ISettingsReader не может быть разрешен:

public HomeController(ISettingsReader settingsReader) 
{ 
} 

Я бы предположил, что, поскольку я зарегистрировал SettingsManager, чтобы быть моим ISettingsWriter, и ISettingsWriter наследует ISettingsReader, Unity будет достаточно умным, чтобы выяснить, что SettingsManager также является ISettingsReader?

Почему я должен делать в явном виде:

myContainer.RegisterType<ISettingsReader, SettingsManager>(); 
myContainer.RegisterType<ISettingsWriter, SettingsManager>(); 

ответ

3

Причина вам нужно явное регистрации для обоих типов базовых что Unity нужно конкретно знать, что вы хотите назад, когда вы разрешить ISettingsReader. Случай, который вы ищете, подразумевает преобразование между интерфейсами, которые Unity не поддерживает.

В качестве примера того, почему неявное преобразование может быть проблематичным, может быть любое число различных реализаций интерфейса:

public class SettingsContainer : ISettingsReader { ... } 
public class SettingsThing2 : ISettingsReader { ... } 

Вы могли бы потенциально настроить ваши регистрации так, чтобы IEnumerable<ISettingsReader> (или какой-либо другой коллекции type) автоматически разрешает всем зарегистрированным реализациям ISettingsReader. Или, вы могли бы хотеть только один ISettingsReader, и Unity не знал, какой из них вам дать. Я не говорю, что это хороший дизайн, но это возможно, учитывая ограничения языка C#.

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

+0

Конечно, он должен быть достаточно умен, чтобы выяснить, что SettingsManager - ISettingsWriter! Это то, что я зарегистрировал. Да, может быть много реализаций для ISettingsReader. Но я зарегистрировал только одно - косвенно. Если бы я зарегистрировал второй, явным образом, я бы ожидал, что он будет разрешен. Если у меня есть цепочка из ста интерфейсов с одной реализацией, мне нужно будет зарегистрировать каждый из них, чтобы я мог использовать их как DI? Это не имеет никакого смысла. –

+0

@HristoYankov Извините, эта часть ответа совершенно неясна, я ее переработаю. Хотя я думаю, что ваш ответ подчеркивает, что если вы ничего не зарегистрировали, как это должно знать, существует ли реализация типа? Насколько я знаю, Unity - это контейнер с прямыми сопоставлениями типа, который не делает неявных преобразований - похоже, что вы ищете что-то, что просто не поддерживает. –

+0

Но дело в том, что оно зарегистрировано. 'B: C ',' A: B' -> 'A: C'. 'if (A is C) {}' даст 'true'. Я уверен, что Unity может пройти через свои зарегистрированные реализации и посмотреть хотя бы на первый, который реализует 'C', нет? Но вы можете быть правы, возможно, Единство просто не поддерживает такое глубокое разрешение. –

 Смежные вопросы

  • Нет связанных вопросов^_^