Странные вещи продолжаются: в моем веб-api я добавляю репозиторий в контроллер после разрешения использования Ninject. Репозиторий хранится в частной переменной-члене readonly. Работает отлично! Когда метод api вызывается, я обращаюсь к переменной - только для того, чтобы увидеть, что он неожиданно null!
Псевдо пример:
public class MyController : ApiController {
private readonly IRepo _repo;
public MyController(IRepo repo) {
Guard.AgainstNullArgument("repo", repo); // guarding to
// make sure it not null
// (would throw ex)
_repo = repo; <--- successfully injected
}
// calling this method
public HttpResponseMessage TestMethod() {
_repo.. <--- suddenly null
}
}
Я проследил проблему до крошечной детали: один из методов в контроллере (а не тот, который получает доступ) аннотируется с помощью настраиваемого атрибута, который направляет ninject для перехвата метода с единицей работы. Если я уберу атрибут, все волшебство снова начнет работать.
UnitOfWorkAttribute.cs
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Interface)]
public class UnitOfWorkAttribute : Attribute
{
}
AttributeInterceptionStrategy.cs(для ninject)
StartupConfig.cs(составной корень, конфигурация IoC и т.д.)
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();
}
}
ИЗМЕНИТЬ
Я буквально поставил точки останова всюду, чтобы выяснить, что происходит. Создал деструктор на контроллере, чтобы убедиться, что весь класс не получает мусор, а также изменил член readonly на свойство с помощью getter/setter, где я обрушился на сеттер, чтобы проверить, назначено ли оно дважды. Ничего подозрительного не происходит вообще.
РЕДАКТИРОВАТЬ 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
РЕДАКТИРОВАТЬ 3 *
Код реального мира: http://pastebin.com/SqpR9KNR