Ninject OnePerRequestBehaviour не работает правильно? - PullRequest
6 голосов
/ 11 февраля 2009

Я использовал Ninject в качестве своего IOC в своем веб-приложении. Это здорово, и я думаю, что это работает очень хорошо, однако я пытался зарегистрировать некоторые интерфейсы / классы как OnePerRequestBehaviour, но, похоже, он не использует это поведение. Код работает правильно, но в одном из моих классов он лениво загружает информацию о странице из базы данных, а затем, после загрузки, ей не нужно попадать в базу данных.

Моя проблема в том, что лениво загруженное свойство будет загружаться в моем первом запросе, когда я затем запрашиваю следующую страницу, используется тот же экземпляр класса. Причина, по которой я это знаю, заключается в том, что экземпляр класса не создается снова, а свойство lazly загружено уже установлено.

Этот код находится в классе моего модуля:

public class NinjectModule : StandardModule
{
    public override void Load()
    {
        Bind<IUnitOfWorkDataStore>().To<HttpContextDataStore>().Using<OnePerRequestBehavior>();


        Bind<CmsService>().ToSelf().Using<OnePerRequestBehavior>();
        Bind<CmsRepository>().ToSelf().Using<OnePerRequestBehavior>();
    }
}

Тогда внутри моего Global.asax, который наследуется от NinjectHttpApplication, у меня есть следующее:

        protected override IKernel CreateKernel()
        {
            OnePerRequestModule module = new OnePerRequestModule();
            module.Init(this);

            KernelOptions options = new KernelOptions();
            options.InjectNonPublicMembers = true;

            IKernel kernel = new StandardKernel(options, new NinjectModule());

            return kernel;
        }

Первый вызов CmsService также находится в global.asax для authenticate_request:

protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            if (HttpContext.Current.Request.Url.AbsoluteUri.Contains(".aspx") &&
                !HttpContext.Current.Request.Url.AbsoluteUri.Contains(".aspx/"))
            {
                CmsService facCMS = HttpKernelFactory.Get<CmsService>();
                ContentPage page = facCMS.GetCurrentPage();

                // DO Logic based on the page being brought back
            }
        }

Приведенный выше код GetCurrentPage ():

public ContentPage GetCurrentPage()
{
    if (_currentPage != null)
        return _currentPage;

    return GetCurrentPage(_isAdmin);
}

Итак, как вы можете видеть, переменная _currentPage загружается, только если она не была установлена ​​ранее, что должно быть один раз для запроса, однако Ninject, похоже, не создает CmsService для запроса, а создает его для ограниченное количество времени.

У кого-нибудь есть идеи, почему это не работает для меня, или какой-либо пример кода, где он определенно работает?

Спасибо

1 Ответ

8 голосов
/ 11 февраля 2009

OnePerRequestModule является модулем HttpModule, и для его работы необходимо загрузить его в конвейер ASP.NET. Если вы добавите его в ваш web.config, он должен работать:

IIS7:

<system.webServer> 
  <modules>
    <add name="OnePerRequestModule" type="Ninject.Core.Behavior.OnePerRequestModule, Ninject.Core"/>
  </modules>
</system.webServer>

IIS6:

<system.web>
  <httpModules>
    <add name="OnePerRequestModule" type="Ninject.Core.Behavior.OnePerRequestModule, Ninject.Core"/>
  </httpModules>
</system.web>

Поведение OnePerRequest значительно улучшено в Ninject2 (который еще не выпущен).

...