Пользовательский базовый тип страницы для моих видов бритвы, как использовать замок Виндзор для автоматического подключения свойств? - PullRequest
6 голосов
/ 12 октября 2011

Моя базовая страница выглядит следующим образом:

namespace ASDF.Mvc.ViewEngines.Razor
{
    public abstract class WebViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel>
    {

        public ISomeHelper SomeHelper { get; set; }
    }
}

My views / web.config

<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="ASDF.Mvc.ViewEngines.Razor.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

Как можно настроить это так, чтобы SomeHelper был подключен с помощью Castle.

В настоящий момент все возвращается на круги своя, Я уже подключил ISomeHelper, и все нормально работает для моих контроллеров / хранилищ / классов обслуживания .

Я предполагаюэтот WebViewPage вызывается где-то, где мой контейнер не имеет доступа (как на уровне контроллера).

Как мне заставить это работать?

Ответы [ 2 ]

9 голосов
/ 15 октября 2011

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

Таким образом, в настоящее время мы можем использовать только инъекцию свойств.

Так что одна из возможностей - использовать пользовательский IDependencyResolver. К сожалению, IDependencyResolver не очень хорошо работает с Castle Windsor . Например, с Ninject это был бы кусок пирога. Все, что вам нужно сделать, это украсить свойство SomeHelper атрибутом [Inject]:

[Inject]
public ISomeHelper SomeHelper { get; set; }

и он был бы автоматически подключен Ninject, поскольку он использует собственный IDependencyResolver. Боюсь, что с Виндзором вам придется делать это вручную. Таким образом, вы можете сделать свой контейнер общедоступным в Global.asax, а затем:

public abstract class WebViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel>
{
    protected WebViewPage()
    {
        SomeHelper = MvcApplication.WindsorContainer.Resolve<ISomeHelper>();
    }

    public ISomeHelper SomeHelper { get; set; }
}

Я знаю, что это отстой, но я боюсь, что это суровая реальность. Или, может быть, переключиться на Ninject? Он отлично играет с ASP.NET MVC 3 и его IDependencyResolver.

0 голосов
/ 13 октября 2011

Я думаю, что вам нужно подключиться к сервисному местоположению MVC3, чтобы контролировать, как создаются страницы просмотра.Я еще не использовал MVC3, но нашел статью, в которой описывается функция расположения службы и которая может дать вам «ловушку», необходимую для доступа к WebViewPage до его обработки.

Получив доступ к WebViewPage до его обработки, вы можете использовать Windsor для внедрения свойств вашей страницы просмотра.По умолчанию Windsor выполняет только инъекцию в конструктор, но вы можете найти образец внедрения свойства с помощью метода расширения в блоге, который я сделал пару лет назад на MVC1 ActionFilters.

...