我知道注入一個IoC容器作爲依賴通常被認爲是一件壞事,因爲它基本上與Service Locator反模式相同。然而,有一種情況我認爲它可能是有道理的,尤其是因爲我沒有看到一個簡單的方法。注入IoC容器作爲依賴有多糟糕?
考慮這些類:
// domain class
public class Foo
{
}
// ViewModel
public class FooViewModel
{
[Dependency]
public IBar Bar { get; set; }
[Dependency]
public IBaz Baz { get; set; }
private readonly Foo _foo;
public ViewModel(Foo foo)
{
_foo = foo;
}
}
// Dependencies used by ViewModel
public interface IBar { void Frob(); }
public interface IBaz { void Fiddle(); }
現在假設我要顯示FooViewModel
列表,從Foo
列表建成。要從Foo
創建FooViewModel
一個例子,我有以下選擇:
只是調用構造函數和手動設置的依賴:
var vm = new FooViewModel(foo) { Bar = _bar, Baz = _baz };
這是不切實際的,因爲:
- 創建
FooViewModel
的對象需要具有Bar
和Baz
作爲依賴關係,即使它使用他們只創建FooViewModel
- 如果我添加一個新的依賴
FooViewModel
,我將不得不更新我創建它的一個實例的代碼。
這兩個問題都可以通過創建工廠來解決,但該工廠需要編寫和維護。在這個非常基本的場景中,這不是一個問題,但對於一個大型的真實世界的應用程序來說,如果有許多依賴關係很多的工廠,它會變得非常麻煩。
- 創建
使用IoC容器來解決
FooViewModel
:var vm = _container.Resolve<FooViewModel>(new ParameterOverride("foo", foo));
這需要依賴的照顧,但後來我不得不使用容器在我的視圖模型層,這是壞的(是嗎?)。
我在想一個折衷:創建一個工廠類,只有容器的依賴,並用它來建立FooViewModel
:
public class FooViewModelFactory
{
[Dependency]
public IUnityContainer Container { get; set; }
public FooViewModel CreateFooViewModel(Foo foo)
{
return Container.Resolve<FooViewModel>(new ParameterOverride("foo", foo));
}
}
這樣,我有一個非常簡單的工廠這很容易維護,而且只有容器作爲依賴項的類是工廠,而不是實際的業務相關代碼。
您是否看到這種方法的缺點?我錯過了一個更好/更簡單的解決方案嗎?
謝謝,但我認爲你錯過了我的問題的重點......我已經在我的問題中提到過這種方法,問題是如果您有很多依賴關係,很難維護。我正在尋找的是關於使用IoC容器的反饋。 –