I’m trying to inject a property into an ActionFilter of mine called UnitOfWorkAttribute. I have this code:
[Inject]
public IUnitOfWork UnitOfWork { get; set; }
Before that gets executed, I tell Ninject to resolve this with:
Bind<IUnitOfWork>().To<NHibernateUnitOfWork>().InThreadScope();
My problem is that in my UnitOfWorkAttribute class, whenever I try to use my UnitOfWork property, It comes through as Null. This is my interface:
public interface IUnitOfWork : IDisposable
{
void Begin();
void Commit();
void Rollback();
}
and this is my concrete:
public interface INHibernateUnitOfWork : IUnitOfWork
{
ISession Session { get; }
}
public class NHibernateUnitOfWork : INHibernateUnitOfWork
{
private readonly ISessionSource sessionSource;
private ITransaction transaction;
private ISession session;
private bool disposed;
private bool begun;
public NHibernateUnitOfWork(ISessionSource sessionSource)
{
this.sessionSource = sessionSource;
Begin();
}
//.......
}
I am fulfilling the interface under the //……
What am I doing wrong here?
The problem is that Ninject never gets a chance to “do it’s thing” on the ActionFilter, that’s handled internally in MVC by the
FilterAttributeFilterProvider. What you need to do is to tell MVC to use a customFilterAttributeFilterProviderwhere you can intercept the filters before they are executed. Allow me to demonstrate:Say I have this interface and implementation:
Then I have an ActionFilter:
And then we have a controller:
If you were to run this now as is, obviously Foo would still be null inside the MyActionFilter, so let’s keep going….
Let’s set up the Ninject DependencyResolver:
Now let’s use that in the Global.asax:
Getting closer, but MVC still doesn’t have a way to use the Ninject kernel when creating the Action Filters. Here’s where we’ll make that happen.
First:
What’s happening here is that we’re creating a custom FilterAttributeFilterProvider class. In the OnActionExecuting method, right after we get all the filters through the base implementation, we can call Ninjects Inject method which will inspect the instance and see if it can inject anything into it (using the Inject attribute).
The final piece of the puzzle is to set up the binding for our custom FilterAttributeFilterProvider:
Global.asax:
Now, when MVC goes to get an
IFilterProvider(it does so automatically through the DependencyResolver) it won’t get the defaultFilterAttributeFilterProviderrather it’ll get our customNinjectFilterProviderand our Foo instance will thus be populated inside the custom Action Filter.