依赖注入问题

6
我有一个关于依赖注入模式的问题。 我的问题是... 如果我选择构造函数注入,为我的类注入依赖项,那么我得到的是一个带有许多参数的“大”构造函数。 如果我在某些方法中不使用一些参数怎么办? 例如,我有一个服务公开了许多方法。还有一个具有10个参数(所有依赖项)的构造函数。但并非所有方法都使用所有依赖项。有些方法只会使用一个依赖项,另一个方法将使用3个依赖项。但是DI容器将解决它们,即使没有用到也会被解决。
对我来说,这是使用DI容器的性能惩罚。这是真的吗?
5个回答

7

看起来你的类做了太多的事情,不符合SOLID(单一职责原则)中的S,也许你可以将这个类分成多个更小的类,减少依赖关系。并非所有方法都使用所有依赖项的事实表明了这一点。


1

通常注入许多依赖项的性能惩罚很低,但这取决于您选择的框架。有些框架会即时编译方法。您需要测试一下。许多依赖项确实表明您的类正在做太多事情(就像Ruben所说的那样),因此您可能需要查看一下。如果创建一个经常不使用的依赖项实例会导致性能问题,则可能需要引入工厂作为依赖项。我发现使用工厂可以解决许多关于依赖注入框架的问题。

// Constructor
public Consumer(IContextFactory contextFactory)
{
    this.contextFactory = contextFactory;
}

public void DoSomething()
{
    var context = this.contextFactory.CreateNew();
    try
    {
        // use context here

        context.Commit();
    }
    finally
    {
        context.Dispose();
    }
}

0

您还可以将一些暂时不需要的依赖项隐藏在懒惰提供者后面。例如:

public DataSourceProvider implements Provider<DataSource> {

    public DataSource get() {
         return lazyGetDataSource();
    }

}

Provider接口javax.inject包的一部分。


0

实际上,在构建 DI 容器时,您无法知道运行时使用了哪些方法。您必须处理这种性能损失,或者如果您知道有许多情况仅使用了少量依赖项,则可以将容器拆分为几个小容器,这些容器具有较少的注入依赖项。


0

正如rube所说,您应该审查类的设计以遵循SOLID原则。

无论如何,如果不是真正必要的话,我习惯于使用属性设置器依赖项而不是构造函数。这意味着您可以为每个所需的依赖项创建一个属性。这也有助于测试类,因为您可以将仅需要的依赖项注入到您正在进行测试的上下文中,而不必将所有依赖项都存根化,即使您不需要它。


1
应该尽可能避免可变状态。 - L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
我同意你的观点。在我的回答中,我同意Rube的说法,他可能应该重新审查他的类设计。我的第二个评论只是一个实际的建议 :-) - Massimiliano Peluso

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接