Reputation: 4662
I am using Ninject and the MVC3 extension installed with nuget. My kernel setup code is in the App_Start/NinjectMVC3.cs file. Everything works great in controllers, but I can't figure out how to (properly) bind interfaces in the Global.asax.cs MvcApplication code.
I ended up using a hack (creating a public NinjectMVC3.GetKernel() method that returns bootstrap.kernel). However, that will be deprecated, and there must be a proper way to do this that I am not seeing.
Here is my code:
public class LogFilterAttribute : ActionFilterAttribute
{
private IReportingService ReportingService { get; set; }
public LogFilterAttribute( IReportingService reportingService )
{
this.ReportingService = reportingService;
}
...
}
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters( GlobalFilterCollection filters )
{
filters.Add( new HandleErrorAttribute() );
filters.Add( new LogFilterAttribute() );
}
...
protected void Application_Start()
{
...
RegisterGlobalFilters( GlobalFilters.Filters );
// NOTE hack:
var kernel = NinjectMVC3.GetKernel();
var logger = kernel.Get<ILogger>();
var bw = new BackgroundWork(logger);
Application["BackgroundWork"] = bw;
bw.Start();
}
}
There are two interfaces I am interested in. The first is just binding an object to a Global variable (the ILogger for the BackgroundWork).
And the second is for an ActionFilter. I read http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/, but I don't see how it plugs into the actual registration (filter.Add).
I don't want to use the Property Inject if I can avoid it.
Any thoughts on the proper way to do this? Thanks
Upvotes: 16
Views: 7044
Reputation: 122654
MVC 3 introduces the DependencyResolver
which is populated into a singleton, and the Ninject extension supports it. You could use that in your MvcApplication
class if you need it:
protected void Application_Start()
{
// ...
var logger = DependencyResolver.Current.GetService<ILogger>();
}
Now I should point out that it is unnecessary to do this with action filters. In Ninject.MVC3 you are supposed to use the BindFilter
syntax, like so:
// Declare empty attribute
public class MyFilterAttribute : FilterAttribute { }
// Dependency module
public class MyModule : NinjectModule
{
public override void Load()
{
// Other bindings
// ...
this.BindFilter<MyActionFilter>(FilterScope.Action, 1)
.WhenControllerHas<MyFilterAttribute>();
}
}
Note that you have to use this
because BindFilter
is an extension method, and you also have to reference the Ninject.Web.Mvc.FilterBindingSyntax
namespace.
Upvotes: 24