2013-04-11 91 views
3

SimpleInjector驗證過程中,我有內置到我的解決方案,它具有使用SimpleInjector的GetAllInstances()方法找到所有事件的訂戶的訂閱實例化過程專有的事件模型與IIS快遞/ Visual Studio中

public IEnumerable<ISubscriber<T>> GetSubscriptions<T>() 
    where T : IEvent 
{ 
    return _container.GetAllInstances<ISubscriber<T>>(); 
} 

我取決於我是否登記的ISubscriber或不

這一切情況得到性能上的巨大的差異就是我用來註冊ISubscriber

012碼

當我引導容器不調用RegisterManyForOpenGeneric容器檢驗需要大約11秒,並返回結果:

配置警告:未檢測到警告。

註冊記憶:計數= 158

然而,當我取消調用RegisterManyForOpenGeneric容器驗證約需72秒並返回結果:

配置警告:136容器登記的類型已被檢測到181種成分參考

註冊:計數= 475

我的問題是 - 這是好的,還是我在這裏做錯了什麼?我加入更多ISubscriber類所有的時間和啓動,現在(的方式)太慢......


更新

看來,這僅僅是一個項目的WebAPI運行內部的問題Visual Studio。從控制檯應用程序引導需要15秒鐘在Visual Studio中運行。將WebAPI項目部署到IIS後,驗證需要6秒鐘。

+2

您使用的是最新版本的SimpleInjector?它使用戶能夠在瀏覽引導代碼時查看任何容器驗證失敗的所有細節。 – 2013-04-11 22:39:14

+0

@FacioRatio是使用2.2 – qujck 2013-04-11 22:39:58

回答

1

如果沒有致電Verify(),Simple Injector容器將在第一次請求時回退到某種「準時」編制委託。在這種情況下,容器通常會創建一個委託來創建整個對象圖(即「根」對象+其所有直接和間接依賴關係)。由於委託是爲整個對象圖構建的,因此通常只編譯一個委託。

將此方法與調用Container.Verify()方法相比較。被調用時,此方法迭代所有註冊併爲每個註冊請求一個實例。這會強制爲容器中的每個註冊編譯委託(不僅針對直接請求的根類型)。

換句話說,在調用Verify時會有很多開銷,所有這些生成和編譯都是在應用程序的啓動階段完成的,相比之下,您所獲得的即時類行爲。在啓動期間調用Verify()不適合每個應用程序。完成Verify()所需的時間取決於很多因素,例如:

  • 您的機器的功率。
  • 無論你是否在調試器內部運行。
  • 容器中的註冊數量。
  • 使用特殊功能。正如您已經注意到應用裝飾器可能會影響編譯過程。當裝飾器包含泛型類型約束時,這尤其適用。

這是件好事在啓動過程中總是叫Verify(),直到......

,直到配置變得太大調用Verify()。在這種情況下,您可以執行以下操作:

  1. 防止在連接調試器時調用Verify,因爲這裏開銷最大。
  2. 如果應用程序啓動時間過長,請在生產啓動期間防止調用Verify
  3. 創建一個單元測試,調用引導程序代碼來請求已配置的容器實例,並讓單元測試在其上調用Verify()。這確保了在將軟件轉出測試,驗收或生產之前,配置錯誤仍然很久以前就被捕獲。 A verifiable configuration非常重要。