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

Joh*_*las 3 .net c# constructor design-patterns inversion-of-control

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

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

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

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

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

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

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

但我现在开始认为UserProvider类应该被打破一点 - 但最终我得到了更多的管道,这正是推动这一问题的原因.

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

小智 7

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

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