2012-07-17 32 views
1

剛剛開始使用ninject進行遊戲 - 我無法擺脫此問題。考慮這種設置:Ninject使用InRequestScope處置訂單

private static void RegisterServices(IKernel kernel) 
{ 
    kernel.Bind<IDataTransaction>().To<DataTransaction>().InRequestScope(); 

    kernel.Bind<IdbAnalytics>().To<dbAnalytics>().InRequestScope(); 
    kernel.Bind<IdbMembership>().To<dbMembership>().InRequestScope(); 

    kernel.Bind<IAnalyticsWork>().To<AnalyticsWork>().InRequestScope(); 
    kernel.Bind<IMembershipWork>().To<MembershipWork>().InRequestScope(); 

    kernel.Bind<ILog>().To<Log>().InRequestScope(); 
    ... 
} 

隨着登錄被注入到上述類別:

public class AnalyticsWork : IAnalyticsWork, IDisposable 
{ 
    private readonly IdbAnalytics _Context; 
    private readonly ILog _Log; 

    public AnalyticsWork(IdbAnalytics Context, ILog Log) 
    {    
     _Context = Context; 
     _Log = Log; 
     _Log.Write(LogEntryType.DEBUG, "Object Created"); 
    } 
    ... 
} 

此問題是Log對象被佈置在所述其他對象的提前(AnalyticsWork/MembershipWork)。有什麼方法可以設置物品應該被處理的訂單嗎?或者這個設置是否有缺陷?

+0

這可能只是一個問題,如果你的類在'Dispose'方法內調用'ILog',這看起來像是一個設計缺陷。你應該儘可能少地使用你的dispose方法。否則,讓你成爲'Log'類的單例。 – Steven 2012-07-17 11:26:13

回答

2

我不使用NInject,但聽起來你是註冊日誌具體作爲共享或每個Web請求(根據InRequestScope可能表示,我再次道歉不使用NInject,所以我不知道什麼那是)。它們全部需要Transient註冊,而不是Scoped,因爲它們將啓動它們的超類寫入日誌中,因爲它們都需要Transient註冊,而不是Scoped調用類。

就配置順序而言,我不認爲你可以用任何IoC容器來控制它,因爲如果另一個類仍然依賴,那麼該對象不能以不同的順序處理。我幾年前剛開始使用IoC容器時遇到過相同的問題,並且認爲,「是的,我將把所有內容註冊爲scoped!」呵呵,那個效果不好。

我會說你的對象只需要註冊不同。只限定你真正需要的項目範圍,其他所有項目爲transientssingletons。我通常遵循以下模式:

代碼一切singleton和代碼thread-safe
如果不是線程安全的,請將其設爲transient並將其註冊爲此。

如果我不使用unit-of-work圖案與我ORM,我將典型地登記自己的ORM容器中,作爲Scoped,這樣他們可以跟蹤請求的生命對象的變化,並調用SaveChanges()後面的(例如實體框架4,或NHibernate的會話等)。

+1

謝謝 - 我想我正在討論這個錯誤。猜猜我有更多的閱讀/計劃要做。 – cschear 2012-07-17 01:56:29

相關問題