Контекстные переменные в Ninject 2 - PullRequest
4 голосов
/ 20 октября 2010

Я нашел эту статью о переменных контекста в более ранней версии 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"));

Возможно ли установить привязку, подобную этой, когда контекст помнит, что она находится в «особом» контексте, когда приходит время для создания C?

1 Ответ

3 голосов
/ 20 октября 2010

Вот некоторые вещи, которые я использую против V2, с ~ 0 усилиями, чтобы очистить их для вас - дайте мне знать, если вы не можете отключить его.

Как вы и предполагали, похоже, нетбыть действительно явным API, который отображает «параметр контекста, даже для вложенных разрешений» в v2 как есть (его присутствие скрыто как третий параметр при перегрузке Parameter ctor).

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

Как обычно, вы должны посмотреть исходный код и тесты - они 'Я дам вам гораздо более подробный и актуальный ответ, чем я.

...