Creating a bootstrapper in ASP.NET MVC 3 using Ninject and DependencyResolver
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.
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.
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:
- Tweak container registration to use the exact constructor you need (e.g. using lambda, I'm pretty sure Ninject should allow for registrations like
kernel.Bind<IBootstrapperTask>().To(() => new RegisterRoutes());
or - (probably the better way) Register something as
RouteCollection
. 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.
精彩评论