Подтвердить что ты не робот

Частный член неожиданно отключился по вызову метода API

Странные вещи продолжаются: в моем веб-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)

http://pastebin.com/Qg6tQWye

StartupConfig.cs(составной корень, конфигурация IoC и т.д.)

http://pastebin.com/fcuSdujj

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

http://pastebin.com/pQULHLT0

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

4b9b3361

Ответ 1

Это странно! Возможно, у вас есть еще один конструктор , который не установил ваш _repo, а затем новый экземпляр контроллера, созданный им.

Ответ 2

Если вы используете Линьф (который вы должны, потому что DynamicProxy все еще нуждается в конструкторе без параметров), то решение довольно легко:. Просто сделайте метод, аннотированный с UnitOfWorkAttribute virtual

Я нашел это через некоторое тестирование: после некоторых попыток я заметил, что все работает, если вы просто удалите plan.Add(new ProxyDirective());. Конечно, перехватчик не применялся, но это указывало на то, что виноват класс прокси.