While working on an ASP.NET MVC application today which uses the Ninject IOC container, I came across a scenario in which I needed a way to figure out whether a given conditional binding would be resolvable or not. Out of the box, the only way to really do this would be to call Get<T>() and catch the ActivationException thrown. Not a very elegant solution, especially since it has the potentially nasty side-effect of actually activating the instance of the binding if it was found.
So I set out to find a better way, and with a few pointers from Nate (the author of Ninject), I ended up with the following extension method for IKernel:
public static class KernelExtensions
{
/// <summary>
/// Determines whether a given type has a resolvable binding
/// </summary>
public static bool HasBindingFor<T>(this IKernel kernel, IParameterCollection parameters)
{
Type service = typeof (T);
// build a context with the parameters
IContext context = kernel.Components.Get<IContextFactory>().Create(service);
context.Parameters = parameters;
// find all the bindings for the type
var registry = kernel.Components.Get<IBindingRegistry>();
ICollection<IBinding> bindings = registry.GetBindings(service);
bool result = bindings.Has(binding => binding.Condition.Matches(context));
return result;
}
}
In my ASP.NET MVC application I can now use this to for example determine whether a given controller exists or not:
bool controllerExists = _kernel.HasBindingFor<IController>(
With.Parameters.Variable("controllerName", controllerName));