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的用户,但我没有注意到这个功能。谢谢。 –