2015-10-13 88 views
1

我在Winforms應用程序中通過將依賴注入到窗體的構造函數中(我知道這不是最佳實踐),但它確實有效,但我在嘗試訪問時遇到了一個stackoverflowexception加載mdi表單。使用Unity IOC時出現StackoverflowException

有什麼方法可以追蹤團結正在試圖解決什麼,並以某種方式找出發生了什麼?

我有一個工作示例,我知道使用此「設計」的作品。

我知道這是不是一個理想的設計,我打算引入一個演示的路線,但現在這應該工作,我不知道爲什麼它不

編輯: 我知道我有服務例如相互參照

public class Service1(IService2, IService3, IService4):IService1 

public class Service2(IService1, IService5):IService2 

這會引起異常嗎?

EDIT2:是的,我剛創建了一個快速的應用程序,這個循環引用在我的第一次編輯中列出,我得到了一個StackOverflowException - 顯然不允許。

+0

「插入表單的構造函數」。這實際上是最好的做法。 Ctor注射在勝利形式中工作良好,並且在注射依賴注射時注射Ctor是最佳實踐。 – Steven

回答

3

當你在VS中發現異常時,進入它並遵循InnerException。 Unity應該打印所有已註冊的類型,並且可以看到丟失的內容。

也看看堆棧跟蹤。

class A { A(B b) { ... } } 
class B { B(A a) { ... } } 

A取決於B反之亦然:通常StackOverflow當你有圓形的依賴條件像這樣出現。 Unity將嘗試注入ctorA a B實例,但B實例需要A實例,該實例同樣需要B等等。

這個例子是一個簡單的一個,但在實際工作中的圓形度是難以察覺因爲可能有依賴關係的更復雜的曲線圖,不同的庫之間,像A - >B - >C - >D - >A(其中「 - >」表示「依賴於」)。

編輯 是的,交叉引用的服務可能會導致您的計算器異常,如果此刻的你正在解決IService1IService1本身尚未註冊;

  1. 登記註冊這兩個IService1,其類型和IService2及其類型:

    解決方案1 ​​ 如果登記註冊類型和解決的兩個步驟(粗略的想法)發生了,你可以繞過這個問題。這一步只做註冊碼,不處理任何其他事情(UI,啓動邏輯,統一解析,http通信等)。

  2. 實際應用邏輯開始;現在你可以解決任何問題。

解決方案2

使用空ctors,做內部Service類的決心。您可以使用RegisterType方法來指定空ctor必須調用:

container.RegisterType<IServiceProvider, ServiceContainer>(new InjectionConstructor()); 

這裏有更多的細節有關circular references with dependency injection using Unity.

解決方案3

使用Lazy<IService>解決。使用這種方式,實際的解決方案將根據需求發生,更具體的是當第一次調用Lazy.Value屬性時。

+0

看到我的編輯..這就是你的意思是,我將有圓形參考 – kurasa

+1

編輯與更多的意見和一些可能的解決方案。 – tomab

+0

解決方案2中的更多信息的URL是空的 – kurasa