开发者

Parameter based bindings in ninject 2.0

I want to use conditional binding in ninject, based on passed parameters. I have something like below:

public class Subject
{
}

public interface ITarget
{
}

public class Target1 : ITarget
{
}

public class Target2 : ITarget
{
}

And now I need to instantiate ITarget interface:

    public void MethodName(IKernel kernel)
    {
        ITarget target1 = kernel.Get<ITarget>(new Parameter("name", new Subject(), true)); // Should be instance of Target1
        ITarget target2 = kernel.Get<ITarget>(); // S开发者_如何学Pythonhould be instance of Target2
    }

I have problems to define proper bindings. I tried the following:

kernel.Bind<ITarget>().To<Target1>().When(Predicate);
kernel.Bind<ITarget>().To<Target2>();

private bool Predicate(IRequest request)
{
    IParameter parameter = request.Parameters.Count == 0 ? null : request.Parameters[0];
    if (parameter == null)
    {
        return false;
    }
    object parameterValue = parameter.GetValue( /*what to put here?*/);
    return parameterValue != null && parameterValue.GetType().IsAssignableFrom(typeof(Subject));
}

but I don't know how to get value of passed parameter. I need to pass IContext instance to GetValue method, but don't know how to get valid instance of IContext. Or maybe there is better way to accomplish my task?

EDIT: BindingMetadata is better way to solve my problem. See Contextual bindings with Ninject 2.0 for details

Regards


Does IRequest.ParentContext not give you enough ?

Also, if all you are looking for is to use a Name to disambiguate multiple instances [and you'll be in a position to provide it each time and are happy to work in that explicit Service Location manner instead of using DI as IDeity intended], then there is a Get overload with a name and a WithName for on the Bind side.

EDIT: Spent some time in Reflector but am still not much wiser. The parameters mechanism seems to be for the purposes of overriding specific values in the context of an actual binding happening, not as part of selecting the binding that applies. Establishing a context is only done in one place internally (though Context has a public ctor) so it doesnt look like there's a neat factory for that.

Does your actual scenario happen to fit the constraint mechanism (of which using a name to filter is just the simplest case). i.e., can you express your Get as something like:

_kernel.Get<ITarget>( (Ninject.Planning.Bindings.BindingMetadata metadata)=>metadata.Has("x") );

Hopefully @Ian Davis will be along soon as I'd love to know the answer too :D


IIRC a request can be part of several contexts. The parameters you see are only parameters that you specify in the Get call. In the example you give, you should be able to pass null as the IContext in order to get your subject instance. Since you supply an object instead of a callback, the parameter constructs a callback as ctx => value -> thus the callback doesn't use the context value you supply.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜