【问题标题】:Dependency Injection - numer of parameters依赖注入 - 参数数量
【发布时间】:2016-01-26 17:08:26
【问题描述】:

我有一个需要大量依赖项的类——用我的话来说,很多依赖项是 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 种方法中的哪一种被认为是一种好的做法?您知道将大量依赖项传递给类的其他方法吗?

【问题讨论】:

  • 您的 DependencyDefinition 看起来像一个服务定位器模式。 Mark Seemann 写了 3 篇关于它的博客,他认为这是一种反模式。最后一个是here。但另请参阅this question

标签: c# dependency-injection dependencies unity-container autofac


【解决方案1】:

显然您的 Step1 并不好,因为它有太多的依赖项。我们需要其他方法。

我强烈反对您的第二步。因为使用依赖注入的想法是让你的依赖对开发者来说是显而易见的。使用您的方法,您创建了一个难以理解的关于 api 的推理。

第 3 步只是一个小技巧。它将负责地推到其他一些采用丑陋构造函数的类。也不推荐。


当您有太多依赖项时,根据定义,您的类正在做太多事情。这也意味着您违反了Single responsibility principle

确定类的职责,重构它们以遵循单一职责原则。那么你的类就不需要太多的依赖了。

Mark Seemann 在这个主题上有一篇很棒的文章 Refactoring to Aggregate Services

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 2019-02-16
  • 1970-01-01
  • 1970-01-01
  • 2019-04-18
  • 1970-01-01
相关资源
最近更新 更多