依赖注入 - 参数的数字

Fka*_*Fka 0 c# dependencies dependency-injection unity-container autofac

我有一个类需要很多依赖 - 在我看来,很多依赖是8和更多.它在IDE中看起来很难看,因为它会破坏行,在一种情况下我有3行构造函数签名:

第一步

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

    ...
}
Run Code Online (Sandbox Code Playgroud)

我决定停止使用这种方法并创建依赖项字典.我取得了什么?漂亮的构造函数签名,但更容易获得运行时异常的可能性.

第二步

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>();
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

但是注册这种类型现在很难看.作为一个例子,我使用的是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>();
Run Code Online (Sandbox Code Playgroud)

当然,为了避免使用第二种方法,我可以创建一个模型,模板或者随意调用它,但它会生成许多其他类,这些类仅用于指定依赖项.

第3步

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)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道有可能通过属性注入,但我想避免它.上3种方法中的哪一种被认为是一种好的做法?你知道还有其他方法可以将大量的依赖关系传递给一个类吗?

Sri*_*vel 7

显然你的Step1不好,因为它有太多的依赖.我们需要一些其他方式.

我强烈反对你的第二步.因为使用依赖注入的想法是让开发人员明白你的依赖关系.通过您的方法,您可以创建一个难以理解的api.

第3步只是一个黑客.它负责任地推动了其他一些需要丑陋构造函数的类.也不推荐它.


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

确定课程的责任,重构他们遵循单一责任原则.那么你的类不需要太多的依赖.

Mark Seemann在本主题Refactoring to Aggregate Services中有一篇很好的文章.

  • 句子"你的班级做了太多事情"描述了一切.谢谢 :) (2认同)