2009-06-04 120 views
2

我正在編寫一個COM對象頂部的API,並且必須將COM對象傳遞到幾乎每種類型和靜態方法中,以便我可以測試每個部分我的API。使用IoC容器的重載方法

現在我的問題是我有一個重載的方法爲那個接受COM對象,但通過IoC解析一個而不是另一個,所以API的用戶不必擔心傳遞在COM對象中,或者我應該刪除重載的方法,只是解決它沒有選項來傳遞它。

有點難以解釋,所以這裏是一個例子;

構造子例子;

FooType(IComObject obj,string table) {} 
FooType(string table) : this(Ioc.Resolve<IComObject>(), table) {} 

或只是

FooType(string table) : this(Ioc.Resolve<IComObject>(), table) {} 

靜態方法示例;

public static SomeType Create(IComObject obj,string table) 
{ // Do some work with obj} 

public static SomeType Create(string table) 
{ 
    return MyClass.Create(Ioc.Resolve<IComObject>(),table); 
} 

或只是

public static SomeType Create(string table) 
{ 
    IComObject obj = Ioc.Resolve<IComObject>(); 
    return MyClass.Create(Ioc.Resolve<IComObject>(),table); 
} 

我與超載最大的擔心是,它會創造出很多的,只是剛愎調用方法。我還有什麼其他選擇,或者是解決這個問題的正確方法?

P.S我真的不想讓用戶不得不在整個應用程序周圍傳遞一個IComObject實例。

+1

這看起來像一個延續的問題在:http://stackoverflow.com/questions/947378/ioc-vs-global-variable-in-library給我? – jerryjvl 2009-06-04 07:01:21

+0

是的,它更像是擔心在這一個污點和可發現性。 – 2009-06-04 07:04:34

回答

4

依賴注入的原則之一是,類的依賴關係應該是明確的外部世界。當一個類本身解析一個依賴關係時(就像你的第二個例子),它違背了這個原則,並且回到了使用單例服務的道路上 - 雖然承認你有點更好,因爲你有IoC容器作爲「逃生孵化「來嘲笑服務對象。

很顯然,在所有對象的構造函數中加載整個參數是相當繁重的,但這正是IoC容器所在的地方。如果它支持自動佈線,並且按照它的設計使用它,那麼您通常會發現自己不得不自己解決很少的實例:您將第一個對象拉出來,並且它已準備就緒 - 配置了所有依賴項 - 並且已準備好配置它們的所有依賴項,等等。出於這個原因,Joshua Flanagan makes the argument IoC容器真的應該被稱爲IoC作曲家。

如果你想避免讓你的API的用戶負擔,那麼有一個焦點對象來包裝你的IoC容器,並通過調用代碼將配置的實例拉出來供消費使用。

2

從我的角度來看,除非您有充足的理由允許重載,否則(重載和解析)都會使您的API不必要地複雜化,並導致您的用戶陷入太多潛在問題。

當你說「P.S我真的不想讓用戶負擔」時,我想你已經回答了你自己的問題。

1

從一個側面,您可以方便地拖放方法如

public static SomeType Create(IComObject obj,string table) 

在所有的,因爲你可以在測試期間註冊IComObject類型的模仿對象,輕鬆地運行這些測試。
但是另一方面,這將打破SoC和Open/Closed原則。你的方法在這種情況下知道得太多(有一些DI等等)。從設計(體系結構)方面來說,使用諸如「創建(IComObject obj,字符串表)」等方法更好,並重構代碼以最小化Ioc.Resolve()的使用,並僅在初始化器,結構或類似的東西中使用它。並且很難解釋如何在不看到所有代碼的情況下重構此代碼。
所以答案是 - 這取決於。
編輯:
關於這種情況有一個very good post。檢查它,它包含的答案=)

1

如果用戶關心IComObject實例,那麼創建一個超負載是一條路。

如果IComObject是您的用戶的實現細節,並且您是唯一一個關心測試的人,那麼您應該公開一個簡單的Factory方法,您的類用於在內部實例化/訪問IComObject

一般來說,如果用戶要關心IComObject,那麼如果您創建一個過載,它將不會成爲負擔。親自作爲開發人員我總是需要儘可能多的選項,因爲我可以得到。