2010-10-20 6 views
4

Я нашел this article в контекстных переменных в более ранней версии Ninject. Мой вопрос в два раза. Во-первых, как я могу получить это поведение с Ninject 2? Во-вторых, выполняют ли переменные контекста по цепочке запросов? Например, предположим, что я хотел бы заменить эти вызовы:Контекстные переменные в 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?

ответ

3

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

Как вы догадались, не существует, по-видимому, явного API, который накладывает «контекстный параметр, даже для вложенных разрешений» в v2 as-is (его присутствие скрыто в качестве третьего параметра при перегрузке 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)); 
    } 
} 

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

+0

Вы также можете найти это полезным: http://stackoverflow.com/questions/1374098/with-parameters-constructorargument-with-ninject-2-0/1375734#1375734 –

+0

Это действительно отличный материал, и я был в состоянии использовать его, чтобы приблизиться к тому, что мне нужно. К сожалению, «унаследованный» параметр теряется всякий раз, когда я привязываюсь к Поставщику или методу. Я мог бы использовать некоторые трюки, чтобы убедиться, что методы передают параметры по линии, но это станет точкой сложности и повторения. Я думаю, что в конечном итоге я просто использую другое ядро ​​для каждого контекста в нашей системе. Спасибо за этот ответ. – StriplingWarrior

+0

@ StriplingWarrior: Рад, что это помогло. BTW Я считаю, что есть способы и средства для распространения контекста на фабриках, подобных тому, что вы говорите (не является ли контекстным параметром для этого ?, то есть context.Get , а не _kernel.Get ? Тесты показывают это. Серьезно взгляните на тесты, и вы будете разбираться в этом. Если это не так, если у вас есть короткий вопрос, как я могу это сделать с этим чистым и спросить его здесь, я или кто-то вроде @Ian Davis будет о. –

 Смежные вопросы

  • Нет связанных вопросов^_^