我最终得到了一个看起来像这样的构造函数,同时试图找到一个我可以轻松测试的对象。
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是否正常。
我可以做几个简化 - 比如我真的不需要为几个适配器传递工厂,因为我可以直接传递适配器,因为它没有内部状态。但我真的在询问参数的数量。
或者更重要的是,我正在寻找保证我不会过火;)
但我开始觉得用户提供程序类应该被打破一点 - 但最后我得到了更多的管道,这正是推动这一问题的原因。
我猜一个子问题是,如果我有这些顾虑,我应该考虑使用服务定位器模式吗?
当使用DI和构造函数注入违反SRP变得非常明显。这实际上是一件好事,而不是DI / IOC的错。如果您没有使用构造函数注入,则该类将具有相同的依赖项,它将不会显示为可见。
您可以在具体示例中执行的操作是隐藏外墙背后的一些相关依赖项。例如,IVehicleRepository和IUserVehicleRepository可以隐藏在IVehicle外观后面。将IUserRepository,IRoleProvider和IAuthenticationProvider放在Facade后面也是有意义的。
在我看来,构造函数的参数很多。以下是我如何处理这个以获得良好的可测试性并减少“代码味道”。
我要说的是在可测试性和实用性之间取得良好的平衡。实现Ioc时,请尝试确定过去在可测试性方面遇到问题的地方以及维护和更改代码时出现问题的原因,因为依赖项太多了。这是你会看到最大利益的地方。