Ввести значение во введенную зависимость
У меня что-то вроде этого:
class Root
{
public Root(IDependency dep)
{}
}
class Dependency:IDependency
{
public Dependency(int val)
{}
}
И я пытаюсь получить ссылку на Root, используя ninject. Так что я настраиваю это так
var module = new InlineModule(mod => mod.Bind<IDependency>().To<Dependency>());
var kernel = new StandardKernel(module);
Я хотел бы добавить в Dependency некоторое значение 'val', которое известно только в момент получения Root-ссылки от ninject.
То, что я хотел бы сделать, это что-то вроде этого:
Kernel.Instance.Get<Root>(With.Parameters.ConstructorArgument("val", 12));
Возможно ли что-то подобное с помощью ninject 1.0?
2 ответа
Parameters.ConstructorArgument
в контексте только один уровень по умолчанию.
Одним из способов передачи параметров по нескольким уровням является использование ContextParameter, но затем нужно что-то захватить и сказать - и теперь мы собираемся использовать это в качестве ConstructorArgument в этом случае. Одна такая конструкция - провайдеры. Смотрите эту страницу dojo для получения подробной информации о провайдерах
Так что вы можете сделать:
class DependencyProvider : SimpleProvider<Dependency>
{
protected override Dependency CreateInstance( IContext context )
{
return new Dependency( (int)context.ParentContext.Parameters.GetOne<ContextVariableParameter>( "masterVal" ).Value );
}
}
public static void Main()
{
var module = new InlineModule(
mod => mod.Bind<IDependency>().ToProvider( new DependencyProvider() )
);
var kernel = new StandardKernel( new[ ] {module} );
Root root = kernel.Get<Root>( With.Parameters.ContextVariable( "masterVal", 12 ) );
}
Или вы можете управлять этим следующим образом:
class RootProvider : SimpleProvider<Root>
{
protected override Root CreateInstance( IContext context )
{
return new Root( context.Kernel.Get<Dependency>( With.Parameters.ConstructorArgument("val", ( int )context.Parameters.GetOne<ContextVariableParameter>("masterVal").Value )));
}
}
public static void Main()
{
var module = new InlineModule(
mod => mod.Bind<IDependency>().To<Dependency>(), // Optional if ImplictSelfBinding is on
mod => mod.Bind<Root>().ToProvider( new RootProvider() )
);
var kernel = new StandardKernel( new[] {module} );
Root root = kernel.Get<Root>( With.Parameters.ContextVariable( "masterVal", 12 ) );
}
Пока вы думаете об этом, рассмотрите моменты, которые я подчеркиваю в этом пункте, чтобы отделить вопросы, связанные с конфигурацией, от привязки объекта в этом ответе.
С Ninject 3 IParameter
с (ConstructorArgument
является одним из них) теперь будет просто "наследоваться" по запросу ребенка, когда они имеют ShouldInherit == true
(см. здесь).
Решение этого вопроса теперь может быть простым:
IResolutionRoot.Get<Root>(new ConstructorArgument("val", 12, true));
где как true
в ConstructorArgument
наборы конструктора ShouldInherit
в true
, Также смотрите здесь