Ответ 1
Это странно! Возможно, у вас есть еще один конструктор , который не установил ваш _repo, а затем новый экземпляр контроллера, созданный им.
Странные вещи продолжаются: в моем веб-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 для перехвата метода с единицей работы. Если я уберу атрибут, все волшебство снова начнет работать.
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Interface)]
public class UnitOfWorkAttribute : Attribute
{
}
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
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
Это странно! Возможно, у вас есть еще один конструктор , который не установил ваш _repo, а затем новый экземпляр контроллера, созданный им.
Если вы используете Линьф (который вы должны, потому что DynamicProxy все еще нуждается в конструкторе без параметров), то решение довольно легко:. Просто сделайте метод, аннотированный с UnitOfWorkAttribute
virtual
Я нашел это через некоторое тестирование: после некоторых попыток я заметил, что все работает, если вы просто удалите plan.Add(new ProxyDirective());
. Конечно, перехватчик не применялся, но это указывало на то, что виноват класс прокси.