Ioc中繁忙的构造函数 - 它们是代码味道吗?

问题描述 投票:3回答:2

我最终得到了一个看起来像这样的构造函数,同时试图找到一个我可以轻松测试的对象。

 public UserProvider(
            IFactory<IContainer> containerFactory,
            IRepositoryFactory<IUserRepository> userRepositoryFactory,
            IFactory<IRoleProvider> roleProviderFactory,
            IFactory<IAuthenticationProvider> authenticationProviderFactory,
            IFactory<IEmailAdapter> emailAdapterFactory,
            IFactory<IGuidAdapter> guidAdapterFactory,
            IRepositoryFactory<IVehicleRepository> vehicleRepositoryFactory,
            IRepositoryFactory<IUserVehicleRepository> userVehicleRepositoryFactory,
            IFactory<IDateTimeAdapter> dateTimeAdapterFactory)

这是对象将拥有的所有依赖项,并且是我拥有的最繁忙的构造函数。但是,如果有人看到这会真的提高一个重要的wtf?

我的目标是最终得到易于测试的逻辑。虽然它需要大量的模拟,但它确实很容易验证我的逻辑。但是我担心我可能会得到太多好事。

我很好奇大多数人实施ioc是否正常。

我可以做几个简化 - 比如我真的不需要为几个适配器传递工厂,因为我可以直接传递适配器,因为它没有内部状态。但我真的在询问参数的数量。

或者更重要的是,我正在寻找保证我不会过火;)

但我开始觉得用户提供程序类应该被打破一点 - 但最后我得到了更多的管道,这正是推动这一问题的原因。

我猜一个子问题是,如果我有这些顾虑,我应该考虑使用服务定位器模式吗?

c# .net design-patterns constructor inversion-of-control
2个回答
6
投票

当使用DI和构造函数注入违反SRP变得非常明显。这实际上是一件好事,而不是DI / IOC的错。如果您没有使用构造函数注入,则该类将具有相同的依赖项,它将不会显示为可见。

您可以在具体示例中执行的操作是隐藏外墙背后的一些相关依赖项。例如,IVehicleRepository和IUserVehicleRepository可以隐藏在IVehicle外观后面。将IUs​​erRepository,IRoleProvider和IAuthenticationProvider放在Facade后面也是有意义的。


3
投票

在我看来,构造函数的参数很多。以下是我如何处理这个以获得良好的可测试性并减少“代码味道”。

  1. 而不是传入工厂来创建类的实例,而只是传递类本身。这会自动将您的依赖项减少一半,因为UserProvider不会关心创建它需要的任何对象(并在必要时随后处理它们)它只会使用给它的内容而不是使用它创建对象所需的工厂它需要的实例。
  2. 从构造函数中删除适配器,只需在UserProvider中创建这些接口的实例。想想你多久需要改变格式化guid的方式。只要您的适配器没有很多依赖项,这仍然是可测试的。

我要说的是在可测试性和实用性之间取得良好的平衡。实现Ioc时,请尝试确定过去在可测试性方面遇到问题的地方以及维护和更改代码时出现问题的原因,因为依赖项太多了。这是你会看到最大利益的地方。

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