簡體   English   中英

使用Ninject在特定對象子樹中的不同綁定

[英]Different binding in specific object subtree using Ninject

我正在使用Ninject在項目中執行依賴項注入,但是遇到了一個問題。 我需要在綁定“我的對象樹”的特定子樹中指定一個例外(意味着包含而不是繼承)。 假設我們只有很少的接口和類(我不包括構造函數和其他不相關的東西):

interface Wheel { ... }
class RoundWheel : Wheel { ... }
class SquareWheel : Wheel { ... }
class Mechanism { Wheel Wheel; ... }
class Bike { Wheel Wheel; ... }
class Items { Mechanism Mechanism; Bike Bike; ... }

我要綁定WheelSquareWheel當它在某種程度上包含在MechanismMechanism可以提高的地方,比如, Item.Mechanism.ContainerForWheel.(any types further on).Wheel )和RoundWheel否則。 現在,讓我們看一下我當前的解決方案:

IKernel kernel = new StandardKernel();
kernel.Bind<Wheel>().To<RoundWheel>();
kernel.Bind<Wheel>().To<SquareWheel>().When(x => x.ActiveBindings.Any(p => p.Service.Name == typeof(Mechanism).Name));

Items items = kernel.Get<Items>();

它的工作原理很像魅力,但看起來非常優雅和次優。 很難理解此過濾的明確目的。 您知道實現此目的的其他方法嗎? 提前致謝。

編輯1我忘記提及我不想在類中添加任何注釋和其他內容。 我想將所有內容保留在內核安裝程序/模塊中。

我認為確實沒有一種更簡單的方法。 您還可以顯式遍歷IContext.ParentRequest並檢查是否存在特定的Mechanism 那將比使用ActiveBindings屬性更加明確。 但是既不會更快也不會導致更少的代碼。

但是您可以做的是應用干凈的代碼並創建自己的When-Extension,因此您將得到:

kernel.Bind<Wheel>().To<SquareWheel>()
      .When(IsDescendantOf<Mechanism1>);

private static bool IsDescendantOf<T>(IRequest request)
{
    return request.ActiveBindings.Any(p => p.Service.Name == typeof(T).Name);
}

或者,使用擴展方法:

kernel.Bind<IWheel>().To<Wheel2>()
      .WhenIsDescendantOf(typeof(Mechanism1));

public static class NinjectWhenExtensions
{
    public static IBindingInNamedWithOrOnSyntax<T> WhenIsDescendantOf<T>(this IBindingWhenSyntax<T> syntax, Type ancestor)
    {
        return syntax.When(request => request.ActiveBindings.Any(p => p.Service.Name == ancestor.Name));
    }
}

順便說一句,您還應該能夠將p.Service.Name == typeof(Mechanism).Name替換為p.Service == typeof(Mechanism) 當名稱匹配時,類型也應該是。 但是,如果使用接口,則必須調整邏輯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM