Использование Ninject с пользовательским типом WebViewPage

Я использую ASP.NET MVC 3 + Ninject в своем приложении, которое отлично работает с моими контроллерами.

У меня также есть пользовательская базовая страница. класс, который наследуется от WebViewPage, и я настроил интерфейс, который я хотел бы внедрить в этот пользовательский класс базовой страницы.

Однако он не работает (мои интерфейсы нулевые), и я предполагаю, что это связано с тем, что Ninject не знает о System.Web.Mvc.MvcWebRazorHostFactory, который, как я подозреваю, должен каким-то образом переопределить или перехватить.

Может ли кто-нибудь указать мне правильное направление, как разрешить моей пользовательской WebViewPage использовать DI?


person Doug    schedule 28.09.2011    source источник


Ответы (2)


Вот возможный обходной путь... Используйте KernelPersister, чтобы указать ядро, и ссылайтесь на него непосредственно из вашего базового представления. Это не так красиво и незаметно, как внедрение конструктора, но оно помогает.

KernelPersister может выглядеть так...

public static class KernelPersister
{
     static IKernel persistedKernel;

     /// <summary>
     /// Persists the provided kernel
     /// </summary>
     public static void Set(IKernel kernel)
     {
          if(persistedKernel == null)
          {
               throw new ArgumentNullException("kernel");
          }

          persistedKernel = kernel;
     }

     /// <summary>
     /// Gets the persisted kernel
     /// </summary>
     public static IKernel Get()
     {
          if(persistedKernel == null)
          {
               throw new Exception("The kernel must be actively set in the persister");
          }
          return persistedKernel;
     }
}

Базовый вид может выглядеть так...

public abstract class MyBaseView : System.Web.Mvc.WebViewPage
{
     /// <summary>
     /// Gets access to the MyService
     /// </summary>
     protected IMyService MyService {get; private set;}

     /// <summary>
     /// ctor the Mighty
     /// </summary>
     public MyBaseView()
     {
          var kernel = KernelPersister.Get();
          this.MyService = kernel.GetService(typeof(IMyService)) as IMyService;          
     }
}
person ctorx    schedule 20.01.2012
comment
Я думаю, что это настолько близко, насколько я могу получить на данный момент. Я пытался избежать локатора службы, но я думаю, что в настоящее время это невозможно. - person Doug; 31.01.2012
comment
Я рассматриваю возможность просмотра источников Ninject.Mvc и реализации решения этой проблемы. Я отпишусь, если у меня все получится. - person ctorx; 31.01.2012

Ну, лучшее решение, которое я нашел до сих пор, — это вручную внедрить зависимость из конструктора класса, используя DependencyResolver:

public class MyView : WebViewPage<MyModel>
{
    IContract _contract;

    public MyView ()
    {
        _contract= DependencyResolver.Current.GetService<IContract>();
    }
}

Поскольку Ninject интегрируется с DependencyResolver, пока он работает хорошо.

С Уважением.

person vtortola    schedule 30.04.2012