Inject value into injected dependency

偶尔善良 提交于 2019-11-27 06:51:21

问题


I'm having something like this:

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

And I'm trying to obtain a reference to Root using ninject. So i configure it like this

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

var kernel = new StandardKernel(module);

I'd like to inject into Dependency some 'val' value that is known only at the moment of obtaining the Root reference from ninject.

What i'd like to do is something like this:

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

Is something like this possible using ninject 1.0?


回答1:


The Parameters.ConstructorArgument in the context only goes one leve deep by default.

One way of passing parameters down multiple levels is by using a ContextParameter, but something then needs to grab that and say - and now we're going to use that as a ConstructorArgument in this case. One such construct is Providers. See this dojo page for details of Providers

So you can do:

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

Or you can manage it as follows:

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

While you're thinking about this, consider the points I make in this point re separating the concerns if configuration from object binding in this response.




回答2:


With Ninject 3 IParameters (ConstructorArgument is one of them) will now simply be "inherited" to child request when they have ShouldInherit == true (see here).

The solution for this question can now be as simple as:

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

where as the true in the ConstructorArguments constructor sets ShouldInherit to true. Also see here



来源:https://stackoverflow.com/questions/2153770/inject-value-into-injected-dependency

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!