将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
程序集。
- IOC :我倾向于将其称为
- UI: MVC应用程序
假设以上所述,我们可以声明您的应用程序Composition Root
或Entry point
是UI 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; } }
此时,您要求在控制器构造函数中注册IHardwareService
。 DI Container
将执行脏任务并将您稍后可以在控制器中使用的实例传递给您。
关于接口的注意事项:我倾向于将这些接口放入自己的程序集中,我只存储接口,例如: Project.Domain.Interfaces
或Project.Infrastructure.Interfaces
,其中每个程序集仅包含域或基础结构接口。
程序集之间的参考:
要将所有这些放在一起, UI只会引用IOC程序集和接口程序集,这些接口程序集包含您在Ninject Module
绑定的接口。
总结以上所有内容:
你自己的课程和界面只是DI容器粘在一起的部分。
希望我清理一下。
编辑:正如@AndreySarafanov在评论中指出的一些好建议,如果你需要在构造函数中要求的接口的不同实现,你可以使用Ninject Factory 。 有关更多信息,请参阅此答案。
- 如何在其他用户更改其用户名时强制注销用户?
- ASP.NET从bin文件夹加载非托管dll
- Angular路由模板URL是否支持ASP.Net MVC 5项目中的* .cshtml文件?
- 选择mvc 4下拉默认值
- 重构类似的CHTML,使用EditorFor和LabelFor呈现不同的属性
- 如何从Asp.Net MVC 5依赖性解析器获取Structuremap IContainer实例
- 在Html.BeginForm MVC4控制器动作中传递多个参数
- Visual Studio 2012 MVC构建错误:名称空间“System.Data.Entity”中不存在类型或命名空间名称“Infrastructure”
- HttpResponseMessage的内容为JSON