使用 Ninject 和 DependencyResolver 在 ASP.NET MVC 3 中创建引导程序
我正在尝试创建一个简单的引导程序。我的 boostrapper 代码如下所示:
public static void Run()
{
var tasks = DependencyResolver.Current.GetServices<IBootstrapperTask>();
foreach (var task in tasks)
{
task.Execute();
}
}
IBootstrapperTask 接口如下所示:
public interface IBootstrapperTask
{
void Execute();
}
我的第一次尝试是通过 bootstrapper 注册路由:
public class RegisterRoutes : IBootstrapperTask
{
private readonly RouteCollection routes;
public RegisterRoutes(RouteCollection routes)
{
this.routes = routes;
}
public RegisterRoutes() : this(RouteTable.Routes)
{
}
public void Execute()
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
}
我的 global.asax 如下所示:
protected void Application_Start()
{
DependencyResolver.SetResolver(new NinjectDependencyResolver());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
Bootstrapper.Run();
}
我的 NinjectDependencyResolver 如下所示:
kernel.Bind<IBootstrapperTask>().To<RegisterRoutes>();
但是,当我尝试运行此代码时,我得到以下结果例外:
激活 VirtualPathProvider 时出错 没有可用的匹配绑定,并且该类型不可自绑定。
激活路径:
3) 将依赖VirtualPathProvider注入到RouteCollection类型的构造函数的参数virtualPathProvider中
2) 将依赖 RouteCollection 注入到 RegisterRoutes 类型的构造函数的参数路由
1) 请求 IBootstrapperTask
任何帮助将不胜感激。
编辑
我的示例工作所需的缺少的绑定是:
kernel.Bind<RouteCollection>().ToConstant(RouteTable.Routes);
如果您使用 Ninject MVC 扩展,则不需要此绑定,因为它已经具有此绑定和其他一些开箱即用的绑定下面的答案。
I am attempting to create a simple bootstrapper. My boostrapper code looks like:
public static void Run()
{
var tasks = DependencyResolver.Current.GetServices<IBootstrapperTask>();
foreach (var task in tasks)
{
task.Execute();
}
}
The IBootstrapperTask interface looks like:
public interface IBootstrapperTask
{
void Execute();
}
My first attempt to was to register routes through the bootstrapper:
public class RegisterRoutes : IBootstrapperTask
{
private readonly RouteCollection routes;
public RegisterRoutes(RouteCollection routes)
{
this.routes = routes;
}
public RegisterRoutes() : this(RouteTable.Routes)
{
}
public void Execute()
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
}
My global.asax looks like:
protected void Application_Start()
{
DependencyResolver.SetResolver(new NinjectDependencyResolver());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
Bootstrapper.Run();
}
And my NinjectDependencyResolver looks like:
kernel.Bind<IBootstrapperTask>().To<RegisterRoutes>();
However, when I try to run this code I get the following exception:
Error activating VirtualPathProvider
No matching bindings are available, and the type is not self-bindable.Activation path:
3) Injection of dependency VirtualPathProvider into parameter virtualPathProvider of constructor of type RouteCollection
2) Injection of dependency RouteCollection into parameter routes of constructor of type RegisterRoutes
1) Request for IBootstrapperTask
Any help would be greatly appreciated.
EDIT
The missing binding that was required for my example to work was:
kernel.Bind<RouteCollection>().ToConstant(RouteTable.Routes);
This binding will not be required if you use the Ninject MVC extension since it already has this binding and a few others out of the box as per the answers below.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
请参阅 https://github.com/ninject/ ninject.web.mvc/wiki/Setting-up-an-MVC3-application 了解如何正确使用
Ninject.Extensions.MVC
。它将添加必要的绑定。See https://github.com/ninject/ninject.web.mvc/wiki/Setting-up-an-MVC3-application about how to use
Ninject.Extensions.MVC
correctly. It will add the necessary bindings.不确定 Ninject 是否准确,但在其他容器中遇到了同样的问题。
看起来容器默认采用带有参数的构造函数,尝试使用自动装配,但不知道要注入什么来代替
RouteCollection
。我会尝试:
kernel.Bind().To(() => 这样的注册; new RegisterRoutes());
或RouteCollection
-kernel.Bind().To(RouteTable.Routes)。 )
更新:正如 Remo 所说,Ninject 的 MVC 扩展已经提供了开箱即用的功能(并且可能是您需要的大多数其他功能)。为了方便起见,使用这些扩展肯定是个好主意。Not sure about exactly Ninject, but encountered the same issue with other containers.
Looks like container takes the constructor with parameter by default, tries to use auto-wiring but doesn't know what to inject in place of
RouteCollection
.I would try to either:
kernel.Bind<IBootstrapperTask>().To(() => new RegisterRoutes());
orRouteCollection
. Id est -kernel.Bind<RouteCollection>().To(RouteTable.Routes)
. Update: as Remo is saying there is MVC Extensions for Ninject where such registration is already provided out of the box (and probaly most of the others you'll need). So, definitely go this way. Using those extension for convenience is a good idea.