【问题标题】:Is it common to aggregate all dependency injection modules?聚合所有依赖注入模块是否常见?
【发布时间】:2020-10-02 09:49:48
【问题描述】:

我在 .NET 项目中使用 Ninject 来处理依赖注入。

我已将我的解决方案分为多个项目:

  • 业务逻辑
  • 前端
  • 视图模型

他们精心挑选了参考资料:

  • FrontEnd 引用了 ViewModels
  • ViewModels 引用了 BusinessLogic

在应用程序的入口点(在我的例子中是前端)初始化 IoC 容器似乎很常见。

但是 FrontEnd 没有对业务逻辑的引用,所以我会得到一个未解决的引用错误。

namespace FrontEnd
{
    class ServiceModule : NinjectModule
    {
        public override void Load()
        {
            
            this.Bind<AccountViewModel>().ToSelf();
            this.Bind<DetailsViewModel>().ToSelf();
            this.Bind<ISessionContext>().To<SessionContext>()
                .InSingletonScope();
            this.Bind<INavigationViewModel>().To<NavigationViewModel>();
            this.Bind<ILoggingService>().To<LoggingService>();
                
            // This will not work because MathClient is in the Business Logic assembly
            this.Bind<IMathProvider>().To<MathClient>()
                .WithConstructorArgument("binding", new BasicHttpBinding())
                .WithConstructorArgument("remoteAddress", new EndpointAddress("http://localhost/server.php"));

        }
    }
}

我觉得在同一个地方聚合所有依赖注入声明是不正确的做法。

我虽然打算在 IoC 容器中声明一些静态方法,以便外部项目可以注册自己的模块,但这会使事情变得更糟,因为这意味着 BackEnd 引用了 FrontEnd:

namespace FrontEnd
{
    class ServiceModule : NinjectModule
    {
        public static void RegisterModule(Module m)
        {
            ...
        }
    }
}

namespace BackEnd
{
    class BackEnd
    {
        public void Init()
        {
            ServiceModule.RegisterModule(new Module() ...)
        }
    }
}

如何将我的所有服务配置到我的 IoC 容器中,而不会在项目之间出现可疑引用(如后端 -> 前端)?

【问题讨论】:

标签: dependency-injection inversion-of-control


【解决方案1】:

将所有依赖注入配置代码放在一个位置,composition root 是一种常见且良好的做法。

假设您决定在项目之间拆分 DI 配置代码。实际上,这在技术上是可行的。您可以在 BusinessLogic 程序集中创建一个单独的 NinjectModule。但在那之后,无论如何你都必须在你的FrontEnd 程序集中加载这个模块。这意味着您仍然需要添加从FrontEnd 程序集到BusinessLogic 程序集的引用。

只需在顶级程序集中配置所有服务。如果您需要添加一些对低级模块的引用,请执行此操作。这比从 BusinessLogic 程序集向后引用某些顶级程序集或从 BusinessLogic 程序集引用到 DI 库要好得多。

请参阅 Mark Seemann 的 article。你的作文代码应该是

尽可能靠近应用程序的入口点

和:

DI Container 只能从 Composition Root 引用。所有其他模块都不应引用容器。

【讨论】:

    猜你喜欢
    • 2011-08-30
    • 2015-03-16
    • 1970-01-01
    • 2011-01-27
    • 2011-06-02
    • 1970-01-01
    • 2017-06-05
    • 2011-09-22
    • 2015-10-06
    相关资源
    最近更新 更多