依赖注入--参数数量

问题描述 投票:0回答:1

我有一个需要很多依赖关系的类--在我看来,很多依赖关系是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种方法中,哪一种被认为是一种好的做法?你知道有什么其他方法可以将大量的依赖关系传递给一个类吗?

c# dependency-injection dependencies unity-container autofac
1个回答
7
投票

显然,你的Step1并不好,因为它有太多的依赖关系。我们需要一些其他的方法。

我强烈不鼓励你的 第二步. 因为使用依赖注入的想法是让你的依赖对开发者来说很明显。用你的方法,你创造了一个很难推理的api。

第三步只是一个黑客。它把负责任的东西推到了其他类中,在那里它采取了丑陋的构造函数.也不推荐这样做。


当你有太多的依赖关系时,从定义上来说,你的类在做太多的事情。这也意味着你违反了 单一责任原则.

确定类的职责,按照单一职责原则重构它们。这样你的类就不需要太多的依赖关系了。

Mark Seemann在这方面有一篇很好的文章。重构为聚合服务.

© www.soinside.com 2019 - 2024. All rights reserved.