2012-09-10 50 views
-1

在這個問題: Examples of IoC Containers.net IoC如何處理構造函數中的異常?

有,警告,在構造函數拋出的異常是難以調試/手柄,因爲國際奧委會吃他們一個答案。隨後的評論說,這不再是事實。

.net IoCs今天如何減輕這個缺陷,還是有一些仍然在這裏受苦?

我對任何.net IoC感興趣,至少有2個組織使用(不僅僅是作者基本上),但如果你需要一個列表:Windsor,StructureMap,Autofac,Ninject。

+0

我會保持這種打開狀態,但IoC只是一種做事的方式,而您要求的是特定於實現的方式;從本質上講,你需要一個實現如何處理的列表(如果他們確實以這種方式處理它)。也就是說,你對具體的IoC實現有一個具體的問題,那麼這會更具建設性。 – casperOne

+2

@casperOne - 我的2美分,但我認爲你有點關閉鏈接的重壓;雖然我明白你爲什麼關閉了最近的帖子,但人們認爲這個問題值得回答。你應該給我們一個機會,恕我直言,如果我們認爲這是一個不好的問題,我們有我們自己的工具向社區或版主表明。 kthx。 – KeithS

+1

我們無法列出每個容器的工作原理。只需決定你喜歡哪個容器,然後再進行測試。就像在代碼中註冊一個服務的五行代碼,然後在Resolve期間拋出一個異常。 – jgauffin

回答

1

我知道一個事實,即如果結構圖中出現異常,那麼StructureMap會冒出異常,但使用此規則會出現一些奇怪的細微差別。例如,如果您正在使用SingletonPattern調度程序,並且您的分配的Singleton在程序執行的較早階段已經安靜地崩潰,那麼StructureMap會愉快地將崩潰的實例輸入到任何請求單例類型的東西中。那時很難說會發生什麼,這一切都取決於你的程序如何處理對崩潰實例的訪問。

但是,如果您嘗試使用無效或類型不匹配的參數調用對象的構造函數,它會在調用該調用點時拋出一個描述性錯誤,作爲將返回給您的某個示例。該設置通常會正常工作,但你可以用基本的單元測試(NUnit的)測試提前完成此項:

[Test] 
public void Assert_registry_is_valid() 
{ 
    ObjectFactory.AssertConfigurationIsValid(); 
} 

我一定會永遠,永遠,永遠曾與StructureMap吞嚥錯誤的問題。通常很容易獲得有用的信息和完整的堆棧信息。

2

顯然這取決於您使用的IoC容器。根據我的經驗,很少有例外情況被「吞噬」,它們在決議時被報告。如果你遵循一個通用的最佳做法,除了接受和驗證構造函數中的依賴之外,不做任何其他的事情,那麼你應該沒問題。

下面是團結的例子:

void Main() 
{ 
    IUnityContainer container = new UnityContainer(); 
    container.RegisterType<IAnimal, Dog>(); 

    // Exception thrown on this line 
    var x = container.Resolve<IAnimal>(); 
} 

public interface IAnimal 
{ 
} 

public class Dog : IAnimal 
{ 
    public Dog() 
    { 
     throw new Exception(); 
    } 
} 

報告此(我認爲這是非常翔實):

ResolutionFailedException: Resolution of the dependency failed, type = "UserQuery+IAnimal", name = "(none)". 
Exception occurred while: Calling constructor UserQuery+Dog(). 
Exception is: Exception - Exception of type 'System.Exception' was thrown. 
----------------------------------------------- 
At the time of the exception, the container was: 

Resolving UserQuery+Dog,(none) (mapped from UserQuery+IAnimal, (none)) 
Calling constructor UserQuery+Dog() 
+0

因此,在Unity的情況下,您不會知道構造函數中發生的異常,因爲Container已隱藏它,直到你調用了x.Dump()來檢查異常 - 是否準確? –

+0

沒有抱歉,調用Resolve時拋出異常......我只是在LinqPad中敲了這個示例,而Dump()是一個實用函數,它提供了有關變量的調試信息。我清理了一下這個樣本,並刪除了這個呼叫以避免混淆。 –

1

我知道Autofac將「包裝」異常拋出,而試圖急切地解決依賴關係。 AutofacException的InnerException將是構造函數向容器拋出的異常。所以,你通常通過捕獲AutofacExceptions並鑽入InnerExceptions來處理解析異常。

大多數IOC都有類似TryResolve的方法,它們可以正確地返回true或false布爾值,並且輸出參數在分辨率成功時被初始化。這些方法是「吃」異常的方法,所以如果異常對您有用,請不要使用這些方法。幾乎任何對基本GetInstance或Resolve方法的調用都會嘗試生成一個水合的,構造函數注入的對象,將拋出所選構造函數中發生的任何異常。

+0

您有解析調用中這種區別的容器列表嗎?我看到Autofac和Windsor都有TryResolve。 Ninject有TryGet。結構圖有TryGetInstance。 Unity似乎沒有這種區別,但是許多擴展庫使用包裝器和幫助器來實現它。 –