Jam*_*ees 17 c# asp.net-mvc ninject ioc-container
我对IoC框架很陌生,所以请原谅术语.
所以我所拥有的是一个带有Nininject MVC参考的MVC项目.我的项目中有其他类libarys,例如Domain层,我希望能够在那里使用Ninject框架,但我的所有绑定都在MVC项目NinjectWebCommon.cs
的App_Start
文件夹下:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IHardwareService>().To<WindowsHardwareService>();
kernel.Bind<IStatusApi>().To<StatusApiController>();
}
Run Code Online (Sandbox Code Playgroud)
目前在我的类库中我使用构造函数注入,但有时我不得不对依赖项进行硬编码:
var service = new WindowsHardwareService();
Run Code Online (Sandbox Code Playgroud)
当我希望能够做到以下几点时:
IKernel kernel = new StandardKernel(.....);
var context = kernel.Get<IHardwareService>();
Run Code Online (Sandbox Code Playgroud)
我没有做以下因为我没有任何模块?我读过的所有文档主要针对的是常规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;
}
Run Code Online (Sandbox Code Playgroud)
IoCModules.cs(在Project.Ioc项目中)
public class IoCModules
{
public IKernel GetKernel()
{
var modules = new CoreModule();
return modules.Kernel;
}
}
Run Code Online (Sandbox Code Playgroud)
CoreModule.cs(在Project.IoC.Modules项目中)< - 这是所有项目的所有引用,这是围绕任何循环依赖问题.
public class CoreModule : NinjectModule
{
public override void Load()
{
Bind<IHardwareService>().To<WindowsHardwareService>();
Bind<IStatusApi>().To<StatusApiController>();
}
}
Run Code Online (Sandbox Code Playgroud)
但我现在得到以下内容:
激活IHardwareService时出错
没有匹配的绑定可用,并且该类型不可自绑定.激活路径:
2)将依赖IHardwareService注入到DashboardController类型的构造函数的参数服务中
1)请求DashboardController
建议:
1)确保您已为IHardwareService定义了绑定.
2)如果在模块中定义了绑定,请确保已将模块加载到内核中.
3)确保您没有意外创建多个内核.
4)如果使用构造函数参数,请确保参数名称与构造函数参数名称匹配.
5)如果使用自动模块加载,请确保搜索路径和过滤器正确无误.
kay*_*ess 19
看来你有很多问题需要在这里解答,所以我会努力做到最好.
根据您当前的问题,我将尝试"绘制"您当前实现的简化架构:
WindowsHardwareService
DependencyResolution
集会.假设这一切之上,我们可以说,您的应用程序Composition Root
或者Entry point
是UI MVC项目.使用a的一个主要概念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<IHardwareService>().To<WindowsHardwareService>();
Bind<IStatusApi>().To<StatusApiController>();
}
}
Run Code Online (Sandbox Code Playgroud)
这将是Ninject module
您将注册/加载的Composition Root
.
现在关于组合根:在UI MVC项目中NinjectWebCommon.cs
您可以拥有一个负责加载模块的方法,如下所示.
private static void RegisterServices(IKernel kernel)
{
var modules = new List<INinjectModule>
{
new ServiceModule()
//, new FooModule()
//, new BarModule()
};
kernel.Load(modules);
}
Run Code Online (Sandbox Code Playgroud)
最后你DashboardController
的UI MVC:
public class DashboardController : Controller
{
private readonly IHardwareService _hardwareService;
public DashboardController(IHardwareService hardwareService)
{
_hardwareService = hardwareService;
}
}
Run Code Online (Sandbox Code Playgroud)
此时,您要求IHardwareService
在控制器构造函数中注册实现.该DI Container
会做肮脏的工作,并通过你,你可以在你的控制器后的工作实例.
关于接口的注释:我倾向于将这些接口放入一个自己的程序集中,我只存储接口,例如:Project.Domain.Interfaces
或者Project.Infrastructure.Interfaces
每个程序集中只包含域或基础结构接口.
程序集之间的参考:
要将所有这些放在一起,UI只引用IOC程序集和接口程序集,它们包含您绑定的接口Ninject Module
.
总结以上所有内容:
你自己的课程和界面只是DI容器粘在一起的部分.
希望我清理一下.
编辑:作为@AndreySarafanov在评论中指出的一些好建议,如果你需要在构造函数中要求的接口的不同实现,你可以使用Ninject Factory.有关更多信息,请参阅此答案.
归档时间: |
|
查看次数: |
1040 次 |
最近记录: |