C# 如果我使用一个IocContainer,它应该在任何地方使用吗?
我们使用Ioc容器来解析项目中的大多数对象,但是似乎在任何地方都可以使用它。在运行时,用户处于单个公司Id的上下文中,在我看来,将该公司Id传递到例如存储库或工作单元的构造函数中是合适的。我们可以在运行时对公司Id使用参数覆盖,但是使用C# 如果我使用一个IocContainer,它应该在任何地方使用吗?,c#,inversion-of-control,C#,Inversion Of Control,我们使用Ioc容器来解析项目中的大多数对象,但是似乎在任何地方都可以使用它。在运行时,用户处于单个公司Id的上下文中,在我看来,将该公司Id传递到例如存储库或工作单元的构造函数中是合适的。我们可以在运行时对公司Id使用参数覆盖,但是使用 var uow = IocContainer.Resolve<IUnitOfWork>(new ParameterOverride("companyId", companyId)) 好的,我知道我可能想在某个时候创建一个不同的IUnitOfWork
var uow = IocContainer.Resolve<IUnitOfWork>(new ParameterOverride("companyId", companyId))
好的,我知道我可能想在某个时候创建一个不同的IUnitOfWork实现,然后我可以轻松地将新实现与Ioc配置交换,但我不相信我会这样做。不,有时调用
new
正是您想要的。例如,方法调用的局部对象或狭窄范围
模型对象通常不受IoC容器的控制。您可以为每个新会话或请求范围实例化一个实例,使用从用户传递给您的数据,这些数据在启动时IoC容器永远不会知道
更新:Honza Brestan关于逻辑单元的观点是正确的。典型的弹簧层排列基于接口:
view->controller->service->persistence
服务使用其他服务、模型对象和持久性来实现用例。我发现IoC的最大优势不在于实现交换(在大多数项目中人们几乎不会这样做),而是迫使您将代码划分为更清晰的逻辑单元,这通常意味着它是可单元测试的,作为一个整体,易于管理和推理
考虑到这一点,我建议您根据项目的逻辑单元来决定“注入粒度”。它可能是5个较大的模块,也可能是几十个不同的小连接器。同样正如达夫莫所提到的,
new
可能是您想要的本地/窄范围的产品。既然您不确定,作为一个快速的折衷方案,为什么不创建一个UnitOfWorkFactory
。在内部,它现在可以返回一个新的实例,如果将来您决定利用IocContainer
,它可以很容易地完成,而无需重构一吨代码。“但是,强制您将代码划分为更清晰的逻辑单元,这通常意味着它是可单元测试的、可管理的,并且更容易作为一个整体进行推理。”-阿门和+1来自我。完全正确
view->controller->service->persistence