Ввести значение во введенную зависимость - PullRequest
8 голосов
/ 28 января 2010

У меня что-то вроде этого:

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

Я бы хотел добавить в Зависимость некоторое значение 'val', которое известно только в момент получения ссылки Root от ninject.

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

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

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

Ответы [ 2 ]

8 голосов
/ 29 января 2010

Значение Parameters.ConstructorArgument в контексте по умолчанию идет только на один уровень.

Одним из способов передачи параметров по нескольким уровням является использование ContextParameter, но затем нужно что-то захватить и сказать - и теперь мы собираемся использовать это как ConstructorArgument в этом случае. Одна такая конструкция - провайдеры. См. эту страницу додзё для получения информации о провайдерах

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

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

Пока вы размышляете над этим, рассмотрите замечания, которые я подчеркиваю в этом пункте, чтобы отделить интересы, если конфигурация от привязки объекта в этом ответе .

2 голосов
/ 23 сентября 2015

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

Решение этого вопроса теперь может быть простым:

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

где в качестве true в конструкторе ConstructorArgument s устанавливается ShouldInherit на true. Также см. здесь

...