Ответ 1
With.ConstructorArgument
для этой цели существовал в 1.0. В 2.0 синтаксис несколько изменился:
With.Parameters.ConstructorArgument с ninject 2.0
См. Ввести значение в вложенную зависимость для получения более подробной информации и примеров использования контекста, поставщиков и аргументов для более правильной передачи таких вещей.
EDIT: Поскольку Стивен решил сделать вид, что мой комментарий не имеет значения, я бы лучше дал понять, что я говорю с некоторыми примерами (для 2.0):
MyClass m = kernel.Get<MyClass>( new ConstructorArgument( "i", 2) );
который для моих глаз очень ясен и точно говорит о том, что происходит.
Если вы в состоянии определить параметр более глобальным способом, вы можете зарегистрировать поставщика и сделать это следующим образом:
class MyClassProvider : SimpleProvider<MyClass>
{
protected override MyClass CreateInstance( IContext context )
{
return new MyClass( context.Kernel.Get<IService>(), CalculateINow() );
}
}
И зарегистрируйте его следующим образом:
x => x.Bind<MyClass>().ToProvider( new MyClassProvider() )
NB бит CalculateINow()
- это то место, где вы ввели бы логику, как в первом ответе.
Или сделайте это более сложным:
class MyClassProviderCustom : SimpleProvider<MyClass>
{
readonly Func<int> _calculateINow;
public MyClassProviderCustom( Func<int> calculateINow )
{
_calculateINow = calculateINow;
}
protected override MyClass CreateInstance( IContext context )
{
return new MyClass( context.Kernel.Get<IService>(), _calculateINow() );
}
}
Что вы зарегистрировали бы так:
x => x.Bind<MyClass>().ToProvider( new MyClassProviderCustom( ( ) => new Random( ).Next( 9 ) ) )
UPDATE: более новые механизмы, которые демонстрируют значительно улучшенные шаблоны с меньшим количеством шаблонов, чем указано выше, воплощены в расширении Ninject.Extensions.Factory
, см.
https://github.com/ninject/ninject.extensions.factory/wiki
Как указано ранее, если вам нужно каждый раз передавать разные параметры, и у вас есть несколько уровней в графике зависимостей, вам может понадобиться сделать что-то вроде этого.
Последнее соображение состоит в том, что, поскольку вы не указали Using<Behavior>
, он будет по умолчанию использовать по умолчанию, как указано/дефолтован в параметрах ядра (TransientBehavior
в выборке), что может показать, что factory вычисляет i
на лету спорный [например, если он был кэширован объектом]
Теперь, чтобы прояснить некоторые другие моменты в комментариях, которые FUDed и затушевываются. Некоторые важные вещи, которые следует учитывать при использовании DI, будь то Ninject или что-то еще:
-
Как можно больше сделать путем инъекции конструктора, поэтому вам не нужно использовать специальные атрибуты и трюки, специфичные для контейнера. Там есть хорошая запись в блоге, которая называется Отображается ваш контейнер IoC.
-
Свернуть код, идущий в контейнер, и попросить вещи - в противном случае ваш код будет связан с a) конкретным контейнером (который CSL может свести к минимуму). b) способ, которым весь ваш проект выложен. Есть хорошие сообщения в блогах о том, что CSL не делает то, что, по вашему мнению, делает. Эта общая тема называется Местонахождение службы и Инъекция зависимостей. ОБНОВЛЕНИЕ: см. http://blog.ploeh.dk/2011/07/28/CompositionRoot.aspx для подробного и полного обоснования.
-
Свести к минимуму использование статики и синглетов
-
Не предполагайте, что существует только один [глобальный] контейнер, и ему нужно просто требовать его, когда вам это нужно, как хорошая глобальная переменная. Правильное использование нескольких модулей и
Bind.ToProvider()
дает вам структуру для управления этим. Таким образом, каждая отдельная подсистема может работать сама по себе, и вы не будете иметь низкоуровневые компоненты, привязанные к компонентам верхнего уровня и т.д.
Если кто-то хочет заполнить ссылки на блоги, на которые я ссылаюсь, я был бы признателен (они все уже связаны с другими сообщениями на SO, хотя, так что все это просто дублирование. с целью избежать путаницы в вводящем в заблуждение ответе.)
Теперь, если бы только Джоэл смог войти и действительно поставил меня прямо на какой красивый синтаксис и/или правильный способ сделать это!
UPDATE: хотя этот ответ, несомненно, полезен из числа найденных им номеров, я хотел бы сделать следующие рекомендации:
- Вышеприведенное кажется немного устаревшим и, честно говоря, отражает много неполного мышления, которое почти смущает, поскольку читает Injection Dependency in.net - Запустите и купите его сейчас - это не только о DI, первая половина - полное обращение ко всем проблемам архитектуры, окружающим его от человека, который потратил слишком много времени, вися вокруг тега инъекции зависимостей.
- Пойдите читать Mark Seemann топ-рейтинги здесь, на SO прямо сейчас - вы узнаете ценные методы от каждого