4

我在早期版本的 Ninject 中找到了这篇关于上下文变量的文章。我的问题有两个。首先,如何使用 Ninject 2 获得这种行为?其次,上下文变量是否沿着请求链进行?例如,假设我想替换这些调用:

var a = new A(new B(new C())));
var specialA = new A(new B(new SpecialC()));

... 有了这个:

var a = kernel.Get<A>();
var specialA = kernel.Get<A>(With.Parameters.ContextVariable("special", "true"));

是否可以设置这样的绑定,当需要构造 a 时,上下文会记住它处于“特殊”上下文中C

4

1 回答 1

3

这是我针对 V2 使用的一些东西,大约 0 次努力为您清理它 - 如果您无法解开它,请告诉我。

正如您所推测的那样,似乎没有一个真正明确的 API 可以按原样显示 v2 中的“上下文参数,即使对于嵌套分辨率”的东西(它的存在作为Parameterctor 重载的第三个参数被埋没)。

public static class ContextParameter
{
    public static Parameter Create<T>( T value )
    {
        return new Parameter( value.GetType().FullName, value, true );
    }
}

public static class ContextParameterFacts
{
    public class ProductId
    {
        public ProductId( string productId2 )
        {
            Value = productId2;

        }
        public string Value { get; set; }
    }

    public class Repository
    {
        public Repository( ProductId productId )
        {
            ProductId = productId;

        }
        public ProductId ProductId { get; set; }
    }

    public class Outer
    {
        public Outer( Repository repository )
        {
            Repository = repository;
        }
        public Repository Repository { get; set; }
    }

    public class Module : NinjectModule
    {
        public override void Load()
        {
            Bind<ProductId>().ToContextParameter();
        }
    }

    //[ Fact ]
    public static void TwoDeepShouldResolve()
    {
        var k = new StandardKernel( new Module() );
        var o = k.Get<Outer>( ContextParameter.Create( new ProductId( "a" ) ) );
        Debug.Assert( "a" == o.Repository.ProductId.Value );
    }
}

这里有一些代码[会混淆问题],它演示了我如何在我的上下文中应用它:-

public class ServicesNinjectModule : NinjectModule
{
    public override void Load()
    {
        Bind<ProductId>().ToContextParameter();

        Bind<Func<ProductId, ResourceAllocator>>().ToConstant( ( productId ) => Kernel.Get<ResourceAllocator>(
            ContextParameter.Create( productId ) ) );
    }
}

public static class NinjectContextParameterExtensions
{
    public static IBindingWhenInNamedWithOrOnSyntax<T> ToContextParameter<T>( this IBindingToSyntax<T> bindingToSyntax )
    {
        return bindingToSyntax.ToMethod( context => (T)context.Parameters.Single( parameter => parameter.Name == typeof( T ).FullName ).GetValue( context ) );
    }
}

像往常一样,你应该去看看源代码和测试——它们会为你提供比我更详细和相关的答案。

于 2010-10-20T17:26:50.913 回答