2010-01-28 2 views
7

У меня что-то вроде этого:значение Вводят в закачиваемой зависимость

class Root 
{ 
    public Root(IDependency dep) 
    {} 
} 
class Dependency:IDependency 
{ 
    public Dependency(int val) 
    {} 
} 

И я пытаюсь получить ссылку на корень, используя Ninject. Так я настроить его, как этот

var module = new InlineModule(mod => mod.Bind<IDependency>().To<Dependency>()); 

var kernel = new StandardKernel(module); 

я хотел бы привнести в Dependency какое-то значение «VAL», который известен только в момент получения ссылки Корневой от Ninject.

Что я хотел бы сделать что-то вроде этого:

Kernel.Instance.Get<Root>(With.Parameters.ConstructorArgument("val", 12)); 

ли что-то подобное можно с помощью Ninject 1.0?

ответ

8

Parameters.ConstructorArgument В контексте только по одному углу левого края.

Один из способов передачи параметров на несколько уровней - это использовать ContextParameter, но что-то тогда нужно захватить и сказать - и теперь мы будем использовать это как конструктор конструкторав этом случае. Одна такая конструкция - Провайдеры. См this dojo page for details of Providers

Так что вы можете сделать:

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)); 
    } 

В то время как вы думаете об этом, рассмотрим the points I make in this point re separating the concerns if configuration from object binding in this response.

+0

Я думаю, что я мог бы сделать это немного более просто нравится: Bind () .Чтобы () .WithConstructorArgument ("Вал" (IContext продолжение) => \t \t cont.ParentContext.Parameters. Получить ("вал")); Но я не люблю использовать ParentContext. :(Это – Silviu

+0

@ Сильвиу: попробуй - чем короче, тем лучше. Мне казалось, что мне так же важно, как и ты, что ты спрашивал, но я не мог заставить его работать для меня в контексте, который я пытался его использовать. –

+0

@ Silviu: Вы делали это как часть работы «Bind»? Iff, поэтому, если вы хотите отбросить что-то, что работает в комментариях, я приведу его в примеры. –

1

С Ninject 3 IParameter с (ConstructorArgument это один из них), теперь просто «по наследству» по требованию ребенка, когда они имеют ShouldInherit == true (см here).

Решение по этому вопросу в настоящее время может быть столь же просто, как:

IResolutionRoot.Get<Root>(new ConstructorArgument("val", 12, true)); 

где, как true в ConstructorArgument конструктору устанавливает ShouldInherit в true. Также см here

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

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