Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
351 views
in Technique[技术] by (71.8m points)

ninject - Inject value into injected dependency

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...