Weird stuff going on: In my web api, I inject a repository into the controller upon resolving using Ninject. The repository gets stored in a private readonly member variable. Works perfectly fine! When a api method gets called, I access the variable - only to see that it's suddenly null!
Pseudo example:
public class MyController : ApiController {
private readonly IRepo _repo;
public MyController(IRepo repo) {
Guard.AgainstNullArgument("repo", repo); // guarding to
// make sure it's not null
// (would throw ex)
_repo = repo; <--- successfully injected
}
// calling this method
public HttpResponseMessage TestMethod() {
_repo.. <--- suddenly null
}
}
I've traced down the problem to a tiny little detail: One of the methods in the controller (not the one that get's accessed) is annotated with a custom attribute that directs ninject to intercept the method with a unit of work. If I take the attribute away, everything magically works again.
UnitOfWorkAttribute.cs
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Interface)]
public class UnitOfWorkAttribute : Attribute
{
}
AttributeInterceptionStrategy.cs (for ninject)
StartupConfig.cs (composition root, IoC configuration etc.)
EfUnitOfWorkInterceptor.cs
public class EfUnitOfWorkInterceptor : SimpleInterceptor
{
private readonly IUnitOfWork _unitOfWork;
public EfUnitOfWorkInterceptor(IUnitOfWork unitOfWork)
{
Guard.AgainstNullArgument("unitOfWork", unitOfWork);
_unitOfWork = unitOfWork;
}
protected override void AfterInvoke(IInvocation invocation)
{
if(!_unitOfWork.Commited)
_unitOfWork.Commit();
_unitOfWork.Dispose();
}
}
EDIT
I've literally put breakpoints everywhere to figure out what's going on. Made a destructor on the controller to make sure the whole class doesn't get garbaged and also changed the readonly member to a property with getter/setter where I break-pointed on the setter to check if it's assigned twice. Nothing suspicuous happens at all.
EDIT 2
Stack
Ninject.Extensions.Interception.dll!Ninject.Extensions.Interception.Injection.Dynamic.DynamicMethodInjector.Invoke(object target = {EIT.Management.Configuration.Web.Api.Controllers.SetupGroupController}, object[] arguments = {object[2]}) Unbekannt
Ninject.Extensions.Interception.dll!Ninject.Extensions.Interception.Invocation.Invocation.CallTargetMethod() Unbekannt
EDIT 3*
Real world code: http://pastebin.com/SqpR9KNR
Constructor
Event.. have you thought about storing that in a Session variable – Jennarepo
argument, but then you are guarding a different variable,unitOfWork
against null. Also, you should let the action execute with the null reference, and then capture the full stack trace to add to your question. I am curious what the caller of the action method with the null controller dependency is, MVC or Ninject (or some other tool). – BetteTryDo
extension? – Luggagevirtual
method that's being overridden in a more derived type in any of your constructors? – Kuroshio