将Nininject MVC与类库一起使用

我对IoC框架很陌生,所以请原谅这个术语。

所以我所拥有的是一个带有Nininject MVC参考的MVC项目。 我的项目中有其他类libarys,例如Domain层,我希望能够在那里使用Ninject框架,但我的所有绑定都在MVC项目的App_Start文件夹下的App_Start中:

 private static void RegisterServices(IKernel kernel) { kernel.Bind().To(); kernel.Bind().To(); } 

目前在我的类库中我使用构造函数注入,但有时我不得不对依赖项进行硬编码:

 var service = new WindowsHardwareService(); 

当我希望能够做到以下几点:

 IKernel kernel = new StandardKernel(.....); var context = kernel.Get(); 

我没有做以下因为我没有任何模块? 我读过的所有文档主要针对的是常规Ninject库而不是MVC版本。

我需要做什么,以及如何将常规Ninject库与MVC版本一起使用?

更新

这是我尝试过的:

这样做的目的是使每个项目都可以加载模块并获得当前注入的接口。

App_Start / NinjectWebCommon.cs (在MVC项目中)

 private static void RegisterServices(IKernel kernel) { var modules = new IoCModules(); var newKernal = modules.GetKernel(); kernel = newKernal; } 

IoCModules.cs (在Project.Ioc项目中)

 public class IoCModules { public IKernel GetKernel() { var modules = new CoreModule(); return modules.Kernel; } } 

CoreModule.cs (在Project.IoC.Modules项目中)< – 这是所有项目的所有引用,这是围绕任何循环依赖问题。

 public class CoreModule : NinjectModule { public override void Load() { Bind().To(); Bind().To(); } } 

但我现在得到以下内容:

激活IHardwareService时出错

没有匹配的绑定可用,并且该类型不可自绑定。 激活路径:

2)将依赖IHardwareService注入到DashboardController类型的构造函数的参数服务中

1)请求DashboardController

建议:

1)确保您已为IHardwareService定义了绑定。

2)如果在模块中定义了绑定,请确保已将模块加载到内核中。

3)确保您没有意外创建多个内核。

4)如果使用构造函数参数,请确保参数名称与构造函数参数名称匹配。

5)如果使用自动模块加载,请确保搜索路径和filter正确无误。

看来你有很多问题需要在这里解答,所以我会努力做到最好。

根据您当前的问题,我将尝试“绘制”您当前实现的简化架构:

  • 域层:域的核心,业务实体的位置等。
  • 基础架构层:这是您的服务所在的位置,例如: WindowsHardwareService
    • IOC :我倾向于将其称为DependencyResolution程序集。
  • UI: MVC应用程序

假设以上所述,我们可以声明您的应用程序Composition RootEntry pointUI MVC项目。 使用DI Container的主要概念之一是您在Composition Root设置/在此处执行所有需要的绑定和注册。 在入口点执行此操作的主要目的是避免Service Locator反模式。

通过使用DI Container你不需要new()你的类实现或获取内核,而是要求注册依赖,遵循Inversion Of Control的规则或也称为好莱坞原则。

在philosphy课程之后,我们终于可以实现一些实际的实施。

创建Ninject模块 :IOC程序集中,我们将此文件称为ServiceModule.cs

 using Ninject.Modules; public class ServiceModule : NinjectModule { public override void Load() { Bind().To(); Bind().To(); } } 

这将是您将在Composition Root注册/加载的Ninject module

现在关于组合根:UI MVC项目中NinjectWebCommon.cs您可以拥有一个负责加载模块的方法,如下所示。

 private static void RegisterServices(IKernel kernel) { var modules = new List { new ServiceModule() //, new FooModule() //, new BarModule() }; kernel.Load(modules); } 

最后你的UI MVC中的DashboardController

 public class DashboardController : Controller { private readonly IHardwareService _hardwareService; public DashboardController(IHardwareService hardwareService) { _hardwareService = hardwareService; } } 

此时,您要求在控制器构造函数中注册IHardwareServiceDI Container将执行脏任务并将您稍后可以在控制器中使用的实例传递给您。

关于接口的注意事项:我倾向于将这些接口放入自己的程序集中,我只存储接口,例如: Project.Domain.InterfacesProject.Infrastructure.Interfaces ,其中每个程序集仅包含域或基础结构接口。

程序集之间的参考:

要将所有这些放在一起, UI只会引用IOC程序集和接口程序集,这些接口程序集包含您在Ninject Module绑定的接口。

总结以上所有内容:

你自己的课程和界面只是DI容器在一起的部分。

希望我清理一下。

编辑:正如@AndreySarafanov在评论中指出的一些好建议,如果你需要在构造函数中要求的接口的不同实现,你可以使用Ninject Factory 。 有关更多信息,请参阅此答案。