Возможно, я неправильно использую Unity, но здесь идет. У меня есть пара приложений, которые загружают одни и те же сборки плагинов. Для всех сборок требуется библиотека, и я хочу, чтобы они имели доступ к этой библиотеке через Unity. Однако, чтобы использовать Unity или любую другую платформу IoC, мне пришлось бы написать интерфейс для этой библиотеки. Я, вероятно, сделаю это, но поскольку интерфейс на самом деле не нужен ни для чего, кроме поддержки Unity, я боюсь, что это означает, что я 1) упускаю суть или 2) неправильно применяю фреймворк. Если я избегаю чего-то, что предлагает мне DI, тогда мне придется сделать класс библиотеки одноэлементным, а затем передать его всем конструкторам плагинов или через открытое свойство, и я не хочу этого делать.
Тем не менее, и пока я на самом деле ничего не реализую с Unity, я не получу еще одну деталь - хотя Unity позволит мне запрашивать библиотеку через Resolve <>, мои плагины все равно должны будут иметь ссылку на Unity экземпляр, который создается в основных приложениях. Так что это тот случай, когда ваш единственный вариант - передать ссылку на Unity всем плагинам, но с этого момента это удобно, просто потому, что вы можете использовать Unity для доступа ко всем другим зависимостям?
UPDATE
Я понял, что упустил момент, но, надеюсь, кто-то сможет прояснить для меня - я не должен везде передавать ссылку на Unity! Мне нужно только создать контейнер в моем приложении, а затем зарегистрировать все типы. Затем, когда я создаю экземпляры всех своих плагинов, они просто должны волшебным образом использовать эти зарегистрированные интерфейсы, почти без лишних усилий, верно? В моем случае мои конструкторы должны быть без параметров, потому что мой загрузчик плагинов не может иметь дело с аргументами, и в этом случае мне придется использовать внедрение свойств, чтобы дать им доступ к интерфейсам, верно?
ДРУГОЕ ОБНОВЛЕНИЕ
Я пошел вперед и попробовал Unity. Я зарегистрировал экземпляр моего класса, который нужен всем плагинам. Я также знаю, что со временем у меня возникнет проблема с моим загрузчиком плагинов, поскольку они не содержат параметров (и мне может понадобиться передать его ссылку в Unity, чтобы они работали). Тем не менее, на данный момент я непосредственно создаю плагин, и я делаю это с помощью метода Resolve. Вот как выглядит этот код:
// app code
ICandySettings _candy_settings = new CandySettings();
IUnityContainer unity = new UnityContainer().RegisterInstance<ICandySettings>( _candy_settings);
CandyPlugin _plugin = unity.Resolve<Candy>(); // throws null reference exception, see below.
// plugin code
public class Candy
{
[Dependency]
ICandySettings CandySettings { get; set; }
...
public Candy()
{
CandySettings.GetSetting("box"); // CandySettings is null! why? Didn't Unity do this for me?
}
}
Так что моя проблема сейчас заключается в том, что я ожидал (учитывая мои ограниченные знания), что Unity собирается автоматически установить ссылку CandySettings плагина на любой экземпляр, зарегистрированный через RegisterInstance, но это не так.
РАБОЧИЙ ВАРИАНТ
Если я пропущу вещи с дымом и зеркалами и просто передам свой UnityContainer в конструктор плагина, тогда я могу вызвать Unity.Resolve (), чтобы установить значение моего свойства CandySettings, и все будет прекрасно. Я хотел бы знать, почему атрибут [Dependency] не делает то, что я думал, что будет Если я не ошибаюсь, мне не нужно передавать Unity каждому конструктору в моем загрузчике плагинов. Я должен просто использовать Unity.Resolve (), и он, вероятно, будет работать, если [Зависимость] работает. Однако теперь я понимаю, что все говорят о том, что выбор контейнера IoC заставит его всю вашу команду разработчиков.
MEF!
Пока MEF выигрывает битву за меня. Это довольно просто, и магический дым и зеркала прекрасно работают для моих нужд (в настоящее время). Но я все еще хотел бы, чтобы Unity работал. Я нахожу странным, что для MEF мне нужно только составлять части, а все остальное просто становится на свои места, тогда как я не могу заставить Unity просто вводить вещи автоматически, и мне нужно все разрешить с помощью ссылки на Unity. везде. Это не может быть правдой.
Больше MEF
Мне нравится идея, что я могу очень легко разрешать несколько объектов с помощью MEF, но как насчет случаев, когда я использую шаблон Strategy для определения поведения кода? В настоящее время это так же просто, как изменение ссылки с одной реализации поведения на другую, и это просто работает . Кто-нибудь делает это с MEF? Правильный ли способ сделать это, чтобы использовать ImportMany, а затем использовать дополнительный код, чтобы определить, какое поведение в списке должно вызываться?