Basically, IControllerFactory has a CreateController method that is
called when instantiating controllers (of type IController) based on
the requested URL and is passed a string for the controller name (eg,
"home", "admin", etc). In my Ninject controller module I want to bind
a controller class to each controller name.
Now what I'm struggling with is a way to specify the string key/
controller-name at binding time. The method I've settled on for now is
to create a named context and then bind conditionally on that.
Here's what I mean:
public class NamedContext : StandardContext
{
public string Name { get; set; }
public NamedContext(IKernel kernel, Type service, string name)
: base(kernel, service)
{
Name = name;
}
public static Predicate<IContext> NameEquals(string name)
{
return c => c is NamedContext && ((NamedContext)c).Name
== name;
}
}
(in my Module.Load):
Bind
<
IController
>().To<HomeController>().OnlyIf(NamedContext.NameEquals("home"));
Bind
<
IController
>().To<UserController>().OnlyIf(NamedContext.NameEquals("user"));
(in my implementation of IControllerFactory):
public IController CreateController(RequestContext context,
string controllerName)
{
return kernel.Get<IController>(new NamedContext(Kernel,
typeof(IController), controllerName.ToLower()));
}
My main question is: is this the easiest way? Is there a way that I'm
missing to bind using string keys? All I could find is binding string
constants or passing strings to constructor arguments. I tried to
think about whether attributes could be used, but these can't be added
at runtime.
BTW - this doesn't just apply to string keys obviously - that
NamedContext could equally a generic "KeyContext" or similar with any
type as the key/name.
Cheers,
Michael
Keep up the good work!