Я довольно удобен для внедрения зависимостей, используя NInject в MVC3. Работая в приложении MVC3, я разработал собственную фабрику создания контроллеров, используя NInject, поэтому любой созданный контроллер будет иметь зависимости, введенные в него через эту фабрику контроллеров.
Сейчас я начинаю разрабатывать приложение для Windows, я хочу использовать Application Dependency Injection. каждый объект должен быть создан с помощью NInject, чтобы упростить модульное тестирование. Пожалуйста, помогите мне убедиться, что каждый созданный объект должен соответствовать только фабрике NInject.
Например, если в какой-либо форме окна на Button_Click
событие я пишу:
TestClass testClass = new TestClass()
и TestClass
имеет какую-либо зависимость, скажем, ITest
тогда это должно быть автоматически разрешено. Я знаю, что могу использовать:
Ikernel kernel = new StandardKenel()
//AddBinding()
TestClass testClass = kenel.get<TestClass>();
Но я считаю утомительным делать это каждый раз, когда я хочу создать объект. Это также заставляет разработчика создавать объект определенным образом. Можно ли сделать это лучше?
Могу ли я иметь центральный репозиторий для создания объекта, и тогда каждое создание объекта будет автоматически использовать этот репозиторий?
источник
Ответы:
Для клиентских приложений часто лучше адаптировать шаблон, такой как MVP (или MVVM), и использовать привязку данных из формы к базовому ViewModel или Presenter.
Для ViewModels вы можете внедрить необходимые зависимости, используя стандартную конструкцию Injection.
В корне композиции вашего приложения вы можете подключить весь граф объектов для своего приложения. Вам не нужно использовать DI-контейнер (например, Ninject) для этого, но вы можете.
источник
Приложения Windows Forms обычно имеют точку входа, которая выглядит следующим образом:
Если вы сделаете этот пункт в коде своим корнем композиции , вы сможете значительно сократить количество мест, где у вас есть код, явно вызывающий Ninject, как если бы это был локатор службы.
С этого момента вы вводите все свои зависимости с помощью инжектора конструктора.
Если ваша «зависимость» - это то, что вам нужно иметь возможность создавать несколько раз, тогда вам действительно нужна фабрика:
Вы можете реализовать интерфейс IFactory таким образом, чтобы избежать необходимости создавать массу одноразовых реализаций:
источник
InjectionFactory<T>
реализовывал, то предоставленный код должен работать просто отлично. Есть ли что-то конкретное, с чем у вас проблемы?Type
, но которая гарантировала бы, что объекты, которые он гидратировал для этого,Type
реализуют или расширяют данный универсальный тип. Ничего особенного.Я всегда пишу оболочку адаптера для любого контейнера IoC, которая выглядит следующим образом:
В частности, для Ninject конкретный класс Adapter выглядит следующим образом:
Основная причина для этого состоит в том, чтобы абстрагировать платформу IoC, чтобы я мог заменить ее в любое время, учитывая, что разница между платформами обычно заключается в конфигурации, а не в использовании.
Но, в качестве бонуса, также становится намного проще использовать IoC-фреймворк внутри других фреймворков, которые не поддерживают его. Для WinForms, например, это два шага:
В вашем методе Main просто создайте экземпляр контейнера, прежде чем делать что-либо еще.
И тогда есть базовая форма, из которой происходят другие формы, которая вызывает Inject для себя.
Это говорит эвристике автоматического подключения пытаться рекурсивно внедрить все свойства в форме, которые соответствуют правилам, установленным в ваших модулях.
источник
Хорошее использование Dependency Injection обычно основано на разделении кода, который создает объекты и реальную бизнес-логику. Другими словами, я бы не хотел, чтобы моя команда часто использовала
new
и создавала экземпляр класса таким образом. Как только это будет сделано, нет способа легко заменить этот созданный тип на другой, поскольку вы уже указали конкретный тип.Таким образом, есть два способа исправить это:
TestClass
в свою форму Windows, чтобы он уже имел экземпляр, когда это необходимо. Когда Ninject создает экземпляр вашей формы, он автоматически создает зависимость.IKernel
в свою форму Windows, а затем использовать его для создания экземпляраTestClass
. В зависимости от вашего стиля, есть и другие способы сделать это (внедрение фабричного класса, фабричного делегата и т. Д.).Это позволяет легко поменять конкретный тип TestClass, а также изменить фактическую конструкцию класса теста, не внося изменений в код, использующий класс теста.
источник
Я не использовал Ninject, но стандартный способ создания вещи , когда вы используете IoC, чтобы сделать это с помощью
Func<T>
которойT
является тип объекта , который вы хотите создать. Таким образом, если объектT1
должен создавать объекты типа,T2
тогда конструкторT1
должен иметь параметр типа,Func<T1>
который затем сохраняется как поле / свойствоT2
. Теперь , когда вы хотите создать объекты типаT2
вT1
вызовеFunc
.Это полностью отделяет вас от вашей платформы IoC и является правильным способом кодирования в мышлении IoC.
Недостатком этого является то, что это может раздражать, когда вам нужно вручную подключить
Func
s или пример, когда вашему создателю требуется какой-то параметр, поэтому IoC не может автоматически подключитьFunc
для вас.http://code.google.com/p/autofac/wiki/RelationshipTypes
источник