聚合所有依赖注入模块是否常见?
Is it common to aggregate all dependency injection modules?
我在 .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 容器中,而不会有项目之间的可疑引用(如后端 -> 前端)?
将所有依赖注入配置代码放在一个地方是一种常见的好做法,在 composition root.
假设您决定在项目之间拆分 DI 配置代码。实际上,这在技术上是可行的。您可以在 BusinessLogic
程序集中创建一个单独的 NinjectModule
。但是在那之后,无论如何你都必须在你的 FrontEnd
程序集中加载这个模块。这意味着您仍然需要添加从 FrontEnd
程序集到 BusinessLogic
程序集的引用。
只需在 top-level 程序集中配置所有服务。如果您需要添加一些对 low-level 模块的引用,请执行此操作。这比从 BusinessLogic
程序集向后引用某些 top-level 程序集或从 BusinessLogic
程序集引用 DI-library.
要好得多
请参阅 Mark Seemann 的 article。你的作文代码应该是
as close as possible to the application's entry point
和:
A DI Container should only be referenced from the Composition Root. All other modules should have no reference to the container.
我在 .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 容器中,而不会有项目之间的可疑引用(如后端 -> 前端)?
将所有依赖注入配置代码放在一个地方是一种常见的好做法,在 composition root.
假设您决定在项目之间拆分 DI 配置代码。实际上,这在技术上是可行的。您可以在 BusinessLogic
程序集中创建一个单独的 NinjectModule
。但是在那之后,无论如何你都必须在你的 FrontEnd
程序集中加载这个模块。这意味着您仍然需要添加从 FrontEnd
程序集到 BusinessLogic
程序集的引用。
只需在 top-level 程序集中配置所有服务。如果您需要添加一些对 low-level 模块的引用,请执行此操作。这比从 BusinessLogic
程序集向后引用某些 top-level 程序集或从 BusinessLogic
程序集引用 DI-library.
请参阅 Mark Seemann 的 article。你的作文代码应该是
as close as possible to the application's entry point
和:
A DI Container should only be referenced from the Composition Root. All other modules should have no reference to the container.