gpt4 book ai didi

c# - 通用 IoC 实践——服务相互依赖是错误的吗?

转载 作者:太空狗 更新时间:2023-10-29 20:25:07 25 4
gpt4 key购买 nike

现在我有一些服务在不依赖于 IoC 容器的程序集中定义(在我的例子中是 Ninject)。在主项目中,我有一个用于在容器中注册的数据访问的 IRepository。

this.Bind<IRepository>().To<EntityFrameworkRepository<MyDatabaseEntities>>();

我还注册了 IAuthenticationService 和 IErrorLogger 服务,我想将存储库用于其逻辑的具体实现。但是,我不确定如何最好地完成此操作。目前,我在两个具体实现上的构造函数都采用 IRepository 参数,并在注册它们时将其传入:

this.Bind<IAuthenticationService>().To<MyAuthenticationService>().
WithConstructorArgument("myRepository", ctx => ctx.Kernel.Get<IRepository());

这里我只是告诉容器获取 IRepository 实例并将其传递给构造函数。

让我的服务组件依赖于 ninject 甚至公共(public)服务定位器 (CSL) 我觉得不对,但我也不确定我目前的方式。我正在寻找意见和替代解决方案。

如果我的其他服务不使用 IRepository,我将不得不为每种类型的基础 IRepository 类型创建这些服务的新具体实现(例如,用于假数据和真实数据的 AuthenticationService)。这将是很多逻辑重复。

最佳答案

您的服务程序集不应依赖于 Ninject,而应仅依赖于您为其注册具体类型的接口(interface)。 IoC 容器应该只是将依赖项注入(inject)类的聚合根。另一方面,包含聚合根/Ninject 内核的程序集将依赖于包含具体类型的所有程序集(它还能如何解析它们?)。

一般而言,对于 IoC,您应该应用 Hollywood principle在这里 - 你应该具体对象实例的依赖关系(如果可能的话使用构造函数注入(inject)),而不是让对象实例请求它们的依赖关系。

您用于 WithConstructorArgument() 的示例实际上根本不需要,因为依赖解析是递归的:你已经注册了 IRepositoryIAuthenticationService与容器,所以它知道如何解决这两个问题。因为IAuthenticationService绑定(bind)到 AuthenticationService您不需要指定构造函数参数,因为它的类型是 IRepository并将自动解决。

至于重复 - 当然您必须为 IRepository 创建不同的实现对于不同的存储库类型,假设您希望这些存储库有不同的行为

关于c# - 通用 IoC 实践——服务相互依赖是错误的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9265632/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com