0

我有一個類需要很多的依賴關係 - 在我的角度來說,很多依賴關係是8和更多。它看起來醜陋的IDE,因爲它打破線和在一個情況下,我有3個線構造簽名:依賴注入 - 參數的數量

第一步

public class FooClass 
{ 
    public FooClass(IDependency1 dependency1, IDependency2 dependency2, ..., IDependency8 dependency8, IDependency9 dependency9) 
    { 
     ... 
    } 

    ... 
} 

我決定停止使用這樣的方法和相關的創建的字典。我取得了什麼成就?漂亮的構造函數簽名,但更容易獲得運行時異常。

第二步驟

public class FooClass2 
{ 
    private IDictionary<Type, object> dependencyDictionary; 

    public FooClass2(IDictionary<Type, object> dependencyDictionary) 
    { 
     this.dependencyDictionary = dependencyDictionary; 
     ... 
    } 

    ... 

    public T GetObject<T>() 
    { 
     return (T)this.dependecyDictionary.FirstOrDefault(t => t.Key == typeof(T)); 
    } 

    // USAGE 
    public void FooMethod() 
    { 
     IDependency1 = this.GetObject<IDependency1>(); 
     ... 
    } 
} 

但是登記這樣類型現在是難看。作爲一個示例,我使用AutoFac,但任何其他依賴容器具有相同的行爲。

var builder = new ContainerBuilder(); 
builder.Register(c => new FooClass2(new Dictionary<Type, object>{ 
    {typeof(IDependency1), c.Resolve<IDependency1>()}, 
    {typeof(IDependency2), c.Resolve<IDependency2>()}, 
    ... 
    {typeof(IDependency8), c.Resolve<IDependency8>()}, 
    {typeof(IDependency9), c.Resolve<IDependency9>()}, 
})).As<FooClass2>(); 

當然,要避免使用第二種方法,我可以創建一個模型,模板或調用任何你想要的,但它產生僅用於指定的依賴許多其他類。

第三步

public class FooDependencyDefinition 
{ 

    public FooDependencyDefinition(IDependency1 dependency1, IDependency2 dependency2, ..., IDependency8 dependency8, IDependency9 dependency9) 
    { 
     this.dependency1 = dependency1; 
     ... 
    } 

    public IDependency1 dependency1; 
    public IDependency2 dependency2; 

    public IDependency1 dependency1; 
    public IDependency2 dependency2; 
    ... 
    public IDependency8 dependency8; 
    public IDependency9 dependency9; 
}   

public class FooClass 
{ 
    public FooClass(FooDependencyDefinition dependencyDefinition) 
    { 
     ... 
    } 
} 

我知道有可能通過性注入,但我想,以避免它。上面3種方法中的哪一種被認爲是一種好的做法?你知道任何其他方式將大量的依賴關係傳遞給一個類嗎?

+0

您的DependencyDefinition看起來像服務定位器模式。 Mark Seemann寫了3篇關於它的博客,他認爲這是一種反模式。最後一個是[這裏](http://blog.ploeh.dk/2015/10/26/service-locator-violates-encapsulation/)。但也請參閱[這個問題](http://stackoverflow.com/q/22795459)。 – wimh

回答

7

顯然你的Step1不好,因爲它有太多的依賴關係。我們需要其他方式。

我強烈勸阻你的第二步。因爲使用依賴注入的想法是讓開發人員明顯依賴它。用你的方法,你很難推斷api。

第3步只是一個破解。它將負責任地推到其他需要醜陋構造函數的類。不要推薦它。


當你有太多的依賴關係時,根據定義,你的班級做的事情太多了。這也意味着你違反了 Single responsibility principle

確定類的責任,重構它們遵循單一責任原則。那麼你的課不需要太多的依賴。

Mark Seemann在這個問題Refactoring to Aggregate Services有優秀的文章。

+2

句子'你的班級做了太多事情'描述了一切。謝謝:) – Fka

+0

[Autofac支持聚合服務,如果你選擇走這條路。](http://autofac.readthedocs.org/en/latest/advanced/aggregate-services.html) –

+0

@TravisIllig這太好了。儘管是autofac的用戶,但我沒有注意到這個功能。謝謝。 –