2012-01-17 5 views
1

Я использую реализацию IDependencyResolver для Виндзора с пользовательским WebViewPage, который имеет сервис как свойство (предполагают службу ведения журнала) в рамках проекта MVC3.Кто создает _Layout.cshtml

Услуга вводится во все виды (их создание проходит через IDependencyResolver).

Проблема в том, что в _Layout.cshtml (макет) служба остается пустой.

Итак, вопрос в том, кто создает макет, так как он не создан IDependencyResolver (или, может быть, я просто не вижу очевидного)?

Edit:

public abstract class WebViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel> 
{ 
    public ILocalizer Localizer { get; set; } 
} 

затем

<pages pageBaseType="[full namespace].WebViewPage"> 

в обоих system.web.webPages.razor и system.web секции в web.config из ~/Просмотров и, наконец, преобразователь зависимости:

public class WindsorDependencyResolver : IDependencyResolver 
{ 
    private readonly IKernel kernel; 

    public WindsorDependencyResolver(IKernel kernel) 
    { 
     this.kernel = kernel; 
    } 

    public object GetService(Type serviceType) 
    { 
     return kernel.HasComponent(serviceType) ? kernel.Resolve(serviceType) : RegisterAndResolve(serviceType); 
    } 

    public IEnumerable<object> GetServices(Type serviceType) 
    { 
     return kernel.HasComponent(serviceType) ? kernel.ResolveAll(serviceType).Cast<object>() : new object[] { }; 
    } 

    private object RegisterAndResolve(Type serviceType) 
    { 
     if (!serviceType.IsAbstract && !serviceType.IsInterface) 
     { 
      kernel.Register(Component.For(serviceType).ImplementedBy(serviceType).LifestylePerWebRequest()); 
      return kernel.Resolve(serviceType); 
     } 
     return null; 
    } 
} 

Распознаватель зависимость устанавливается в Global.asax.cs:

var dependencyResolver = new WindsorDependencyResolver(container.Kernel); 
DependencyResolver.SetResolver(dependencyResolver); 

Когда какой-либо вид экземпляра (Index.cshtml) метод GetService из распознавателя зависимостей называется и вид создается контейнером. Для _Layout.cshtml этот метод не вызывается.

Так что, когда я делаю это в Index.cshtml: @Localizer.Localize(....) служба localizaer не равно нулю, но в _Layout.cshtml это null, конкретная проблема в том, я ничего не могу локализовать в представлении (и я не хочу для просмотра каждого поддерживаемого языкового стандарта).

Надеюсь, теперь это яснее.

Edit: Еще нет четкого ответа на этот ... у меня не было времени, чтобы проверить источники MVC, но ответ должен быть там наверняка ...

+2

Почему вы пытаетесь найти информацию о вашем сервисе? – Hammerstein

+0

Лучшим примером может служить служба локализации. – Padel

+0

Я сталкиваюсь с той же проблемой. Вам повезло разобраться в этом? – BrooklynDev

ответ

1

Он создан механизм просмотра Razor. Его базовый тип определяется внутри ~/views/web.config в атрибуте pageBaseType узла pages. По умолчанию это System.Web.Mvc.WebViewPage.

Если вы хотите, чтобы сделать инъекцию зависимостей в шаблоны Razor (независимо от того, если это _layout или какой-либо другой вид), вы можете определить свой собственный тип страницы базы:

public abstract class MyWebViewPage<T> : WebViewPage<T> 
{ 
    public MyWebViewPage() 
    { 
     SomeDependency = DependencyResolver.Current.GetService<IFoo>(); 
    } 

    public IFoo SomeDependency { get; private set; } 
} 

затем в ~/views/web.config установить базовый тип :

<pages pageBaseType="AppName.Controllers.MyWebViewPage"> 

, а затем все ваши шаблоны будут иметь свойство SomeDependency в наличии:

@model MyViewModel 
@SomeDependency.FooBar() 

Обратите внимание, что это может не быть хорошим выбором дизайна в некоторых ситуациях.Если вы намерены ввести какой-то пользовательский HTML-помощник в свое представление, тогда все в порядке. Но если вы намереваетесь внедрить некоторую услугу домена, и ваши взгляды начнут извлекать зависимости слева и справа, а не использовать модели просмотра, тогда вы делаете серьезную ошибку дизайна, потому что ответственность за просмотр не связана с выбором зависимостей. Его ответственность состоит в том, чтобы отобразить информацию, которую он передал в форме модели представления. Откуда эта информация исходит не от ответственности. Контроллер должен координировать выборку данных и помещать их в модель представления, которая передается в представление.

+0

Это именно то, что я делаю. И проблема в том, что я могу вызвать @Localizer (как в примере) в каждом представлении, но в _Layout.cshtml (где он равен нулю). – Padel

+0

@Padel, я не могу воспроизвести проблему. Вы заметили в моем примере, как зависимость извлекается в конструкторе 'MyWebViewPage' с использованием преобразователя зависимостей? Это называется шаблоном локатора службы. По мнению некоторых пуристов, это анти-шаблон по сравнению с инъекцией зависимостей, но это ваша единственная надежда с помощью Razor. Вероятно, в будущих версиях двигателя они обеспечат использование реальной инъекции зависимостей. –

+0

Все реализовано, как указано выше, за одним исключением: вы явно не вызываете преобразователь зависимостей. Преобразователь зависимостей подключает контейнер IoC (например, Windsor) к архитектуре MVC. Я отредактирую свой пост, чтобы все видели, что происходит. – Padel

Смежные вопросы