How to use Ninject with Query Parameters in MVC?
I am following Steven Sanderson's Pro MVC2 book and have a question about using Ninject.
In the sports store example, we have in Global.asax.cs
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
and NinjectControllerFactory
is defined as:
public class NinjectControllerFactory : DefaultControllerFactory
{
//A Ninject "kernet" is the thing that can supply object instances
private IKernel kernel = new StandardKernel(new SportsStoreServices());
protected override IController GetControllerInstance(System.开发者_运维问答Web.Routing.RequestContext requestContext, Type controllerType)
{
return (IController)kernel.Get(controllerType);
}
private class SportsStoreServices : NinjectModule
{
public string QString = null;
public override void Load()
{
Bind<IProductsRepository>().To<SqlProductsRepository>()
.WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString);
}
}
}
As you see the SqlProductsRepository
is taking the connection string from the configuration file. If I need to make a decision here based on the URL query string parameters e.g. if param1=true I want to load from one repository versus the other, how can I do that? I have tried to see how to access query parameters in Load()
method but I am not able to find a prepopulated place for that.
Also is Load()
the right place to make a decision based on query parameters or should I somehow make this decision in Controller?
One would have multiple bindings that have .WithMetadata (or the special case thereof, are .Named()
). Then, when resolving, you need to pass in a metadata filter and/or name parameter into the .Get<>()
call to indicate the bindings. A small but of searching around here will yield examples, but by far the best source of ninject examples is the ninject tests, which are really clean and one of the reasons the ninject docs dont get the love they deserve (i.e. a v2 update).
i.e., you put a name or metadata filter in as an extra param into the:
return (IController)kernel.Get(controllerType, **here**);
As for best practice on how to manage this in more complex situations, I personally would go read Brand Wilson's set of posts on how they did it in MVC 3.
I guess it depends on your destination and aims:
- making a sample do something while you learn - lash in the above
- sort out DI based architecture to make you happy, run and buy Dependency Injection in .NET by Mark Seemann, strongly consider ASP.NET MVC 3 and read the Brad Wilson article series either way
a Module's Load() method only gets called when the application starts and the kernel is intialized. hence, there is no request context to make decisions on.
if it were me, I would inject both repositories into the controller and have the controller make the decisions on which to use. that way you can write unit tests to verify it's making the correct decisions.
精彩评论