Ninject.Web.PageBase все еще приводит к нулевой ссылке на внедренную зависимость - PullRequest
5 голосов
/ 01 марта 2010

У меня есть приложение ASP.NET 3.5 WebForms, использующее Ninject 2.0. Однако, пытаясь использовать расширение Ninject.Web для обеспечения внедрения в System.Web.UI.Page, я получаю нулевую ссылку на мою внедренную зависимость, даже если я переключаюсь на использование локатора службы для предоставления ссылки (используя Ninject ) нет проблем.

Моя конфигурация (из-за простоты):

public partial class Default : PageBase // which is Ninject.Web.PageBase
{
    [Inject]
    public IClubRepository Repository { get; set; }

    protected void Page_Load(object sender, EventArgs e)
    {
        var something = Repository.GetById(1); // results in null reference exception.
    }
 }

... //global.asax.cs

public class Global : Ninject.Web.NinjectHttpApplication
{
    /// <summary>
    /// Creates a Ninject kernel that will be used to inject objects.
    /// </summary>
    /// <returns>
    /// The created kernel.
    /// </returns>
    protected override IKernel CreateKernel()
    {
        IKernel kernel =
        new StandardKernel(new MyModule());
        return kernel;

    }

..

...

public class MyModule : NinjectModule
{
    public override void Load()
    {
        Bind<IClubRepository>().To<ClubRepository>();
        //...
    }
}

Получение конкретного экземпляра IClubRepository через локатор служб работает нормально (используется тот же «MyModule»). То есть

  private readonly IClubRepository _repository = Core.Infrastructure.IoC.TypeResolver.Get<IClubRepository>();

Чего мне не хватает?

[Update] Наконец-то вернулись к этому, и он работает в режиме Classic Pipeline, но не интегрирован. Требуется ли классический конвейер?

[Обновление 2] Проблема с подключением моего модуля OnePerRequestModule (которая была удалена в приведенном выше примере для ясности):

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

        IKernel kernel = new StandardKernel(new MyModule());

        return kernel;
    }

... должно быть:

    protected override IKernel CreateKernel()
    {
        IKernel kernel = new StandardKernel(new MyModule());

        var module = new OnePerRequestModule();
        module.Init(this);

        return kernel;
    }

Объясняя, почему я получаю исключение нулевой ссылки в интегрированном конвейере (для вставленной зависимости Ninject или просто для загрузки страницы для страницы, наследуемой от Ninject.Web.PageBase - что бы ни возникло первым).

Ответы [ 2 ]

2 голосов
/ 02 марта 2010

Это довольно загадочно, потому что из того, что я могу сказать, видно, что у вас все настроено правильно. Из того факта, что вы получаете исключение Null Reference вместо ActivationException, может показаться, что внедрение на уровне страницы не происходит. Обычно это происходит из-за уровня защиты внедряемого свойства, но в зависимости от вашего кода там нет проблем. Вот некоторые вещи, которые вы можете попытаться отследить, что это за проблема:

  1. Вызов Kernel.Inject (this), который инициирует внедрение свойства для Ninject, выполняется в методе OnInit класса PageBase. Если по какой-либо причине этот метод не выполняется, это может привести к проблеме, которую вы видите. Вы можете провести дальнейшее исследование, переопределив метод RequestActivation (), который является методом, вызываемым для фактического внедрения (обязательно вызовите base.RequestActivation ()). Если ваше переопределение никогда не вызывается, значит, есть проблема с OnInit.

  2. InjectAttribute настроен в конфигурации ядра по умолчанию, поэтому нет необходимости указывать его, однако, если вы хотите быть более уверенным, вы можете настроить отображение атрибутов в вашем ядре, настроенном с помощью делать что-то вроде:

    ядро ​​IKernel = новый StandardKernel (новый NinjectSettings {InjectAttribute = typeof (InjectAttribute)}, новый MyModule ());

  3. Экземпляр ядра, используемый классом PageBase для внедрения (а также экземпляр, который должен быть создан с помощью переопределения CreateKernel в вашем Global.asax.cs), хранится в объекте типа локатора службы в Ninject.Web. .KernelContainer. Я хотел бы убедиться, что вы видите свойство Kernel на KernelContainer и что оно не является нулевым из вашего метода Page_Load.

Это все, что у меня есть на данный момент, что касается понимания. Как я уже сказал, отсюда видно, что все ваши утки одеты и выстроены в ряды, поэтому они должны работать ...

Удачи в решении проблемы.

1 голос
/ 04 мая 2010

Это может быть не только для Ninject. Я могу получить то же исключение, работающее в интегрированном режиме без IoC. У меня просто простое приложение asp.net, которое содержит только одну страницу aspx без логики.

В моем файле global.asax у меня есть следующее:

public class Global : HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        this.EndRequest += new EventHandler(Global_EndRequest);
    }

    void Global_EndRequest(object sender, EventArgs e)
    {
        // do stuff
    }

По сути, подписка на событие в application_start вызывает у меня это исключение при работе в режиме интегрированного конвейера. Переключение на классический конвейер или удаление подписки на событие и обработчика устраняет ошибку. Я использую IIS 7.5 на Win7 Enterprise 64bit.

Это может не решить вашу конкретную проблему, но я публикую здесь, поскольку это единственная страница, которая появилась, когда я вставил исключение в Google! Я перенесу свой ответ в отдельный вопрос, когда мне будет позволено задать один. У меня пока нет похвал стека: (

...