2014-07-21 22 views
2

我有一個PriorityQueue,它將Func作爲構造參數。停止Ninject綁定Func <T, T, bool>自動

public PriorityQueue(ISomeOtherInjectedThing other, Func<T, T, bool> cmp_func) {...} 

我束縛,這使用Ninject:

Bind(typeof (IPriorityQueue<,>)).To(typeof(PriorityQueue<,>)); 

我們在代碼和這一部分了bug,我們注意到Ninject似乎產生一個對象FUNC鍵,注入到我們的優先級隊列此,但我們對此沒有約束力。工廠應該拋出一個激活例外,因爲我們沒有通過所需的比較功能。它沒有,如果我調試,我發現這一點:

Ninject.dll!Ninject.KernelBase.Resolve.AnonymousMethod__c(Ninject.Planning.Bindings.IBinding binding) Line 386 + 0x5a bytes C# 

我怎樣才能獲得Ninject拋出預期的異常,而不是默默地生成函數求<>注入?

回答

1

Func-Auto綁定到Func-Factory是Ninject.Extensions.Factory的一個功能。請參閱源文件: FuncModule.cs

如果您爲Func<T, T>創建特定綁定,它仍將覆蓋由FuncModule創建的通用綁定。但正如您注意到的,如果您不創建特定的綁定,則不會有任何例外。

擺脫默認(打開)綁定的最簡單方法是擺脫Factory擴展。

但這可能有點激烈。你也可以做什麼,而不是被禁用Auto-Extension loading

var kernel = new StandardKernel(new NinjectSettings {LoadExtensions = false}); 

那麼你就必須動態地加載擴展 - 這是通過加載其NinjectModule實現完成。例如:

IKernel.Load<FuncModule>(); 

當然的FuncModule你不希望加載,我們正在做這一切來擺脫它。但是您必須爲您實際需要的所有其他擴展模塊執行此操作。 最後,你必須創建一個你所需要的所有工廠擴展綁定:

if (!this.Kernel.GetBindings(typeof(Func<IContext, IResolutionRoot>)).Any()) 
{ 
    this.Bind<Func<IContext, IResolutionRoot>>().ToMethod(ctx => context => context.Kernel); 
} 

this.Bind<FuncProvider>().ToSelf().InSingletonScope(); 
this.Bind<IFunctionFactory>().To<FunctionFactory>(); 
this.Bind<IInstanceProvider>().To<StandardInstanceProvider>(); 

#if !SILVERLIGHT_20 && !WINDOWS_PHONE && !NETCF_35 
this.Bind<IInterceptor>().To<FactoryInterceptor>() 
    .When(request => typeof(IFactoryProxy).IsAssignableFrom(request.Target.Member.ReflectedType)); 
#endif 

注意:如果您在實際使用Func鍵,工廠 ,我會建議「忽略」的問題。如果問題再次出現,你現在知道去哪裏看。 如果這是一個孤立的問題,你也可以用接口替換Func<,>,使事情更加明確(乾淨的代碼)。 當然,這不是一個完美的解決方案。這只是一個艱難的選擇之一;-)

+0

我是否正確理解這一點:如果我只是停止使用工廠擴展(=不要安裝工廠擴展nupkg),問題就消失了? – Wilbert

+0

。 (......填寫消息最小尺寸要求的空間:D) – BatteryBackupUnit

+0

但我也認爲Factory Extensions提供了一些非常有價值的功能。所以我要麼通過特定的接口替換'Func <>',要麼通過禁用自動加載併爲Factory擴展創建一組自定義的綁定來使用擴展的「一半」,正如答案中所述。 – BatteryBackupUnit

相關問題