Что такое IViewLocationExpander.PopulateValues () для in Asp.Net ядро MVC

Я использую ASP.NET ядро MVC. Я реализовал свой собственный ViewLocationExpander, чтобы структурировать свой проект так, как я хочу, и размещать свои взгляды там, где мне нравится.

Это достигается путем реализации класса, который наследует от IViewLocationExpander и большая часть работы происходит в следующим образом:

ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)

все работает довольно сладко, но интерфейс определяет 2-й метод, который я не знаю, как правильно реализовать:

PopulateValues(ViewLocationExpanderContext context)

Я читал статьи по всему интернету об этом интерфейсе, но никто не предоставил много информации о том, что именно этот метод, кроме как говорить неопределенные вещи о том, как это помогает с кэшированием.

Я был бы очень признателен, если бы кто-нибудь мог объяснить, как этот метод используется платформой и как я могу использовать его соответствующим образом, чтобы помочь кэшированию, если это действительно то, для чего он предназначен.

3 ответов


возможно, следующая дополнительная информация взята непосредственно из проблема GitHub MVC могу ответить на ваш вопрос:

кэширование включает в себя Values словарь в его поиске. Если PopulateValues() метод добавляет различную информацию в ViewLocationExpanderContext.Values на ExpandViewLocations() метод будет вызываться только один раз на исходное имя файла, т. е. исходная информация кэшируется с этого момента.

кроме того, конкретный пример, поставленный OP, может помочь поймите еще лучше, по крайней мере, это то, что случилось со мной:

  • его проект имеет представления с тем же именем в двух разных каталогах деревья (скажем Foo и Bar)
  • в зависимости от некоторых данных, извлеченных текущим контекстом действия, представление для поиска должно находиться под одним из этих деревьев

без какого-либо кода PopulateValues(), view engine спросит после чтобы найти представление, используйте представление "стандартные" данные (например ControllerName, ActionName, Area, etc.) для того, чтобы кэшировать фактическое местоположение, где вид найден.

Итак, в случае OP, после кэширования местоположения представления (например, из Foo дерево каталогов) каждый раз, когда требуется представление с тем же именем, оно всегда будет из этого дерева, не будет способа определить, есть ли одно в другом Bar дерево должно было быть фактически поднято.

единственный способ для OP-настроить PopulateValues() путем добавлять специфические, своеобразнейшие детали взгляда к Values словарь: в текущем сценарии это информация, извлеченная из текущего контекста действия.

дополнительная информация используется в два раза: ExpandViewLocations() может использовать их при вызове для определения правильного местоположения, в то время как view engine будет использовать их для кэширования местоположения представления после его обнаружения.


не возились с ним достаточно, чтобы иметь возможность дать вам конкретный ответ, но посмотрите на IViewLocationExpander.PopulateValues(ViewLocationExpanderContext context) на ASP.NET MVC GitHub repo:

public interface IViewLocationExpander
{
    /// <summary>
    /// Invoked by a <see cref="RazorViewEngine"/> to determine the values that would be consumed by this instance
    /// of <see cref="IViewLocationExpander"/>. The calculated values are used to determine if the view location
    /// has changed since the last time it was located.
    /// </summary>
    /// <param name="context">The <see cref="ViewLocationExpanderContext"/> for the current view location
    /// expansion operation.</param>
    void PopulateValues(ViewLocationExpanderContext context);

    // ...other method declarations omitted for brevity
}

формат чтения:

"вызываются RazorViewEngine чтобы определить значения, которые будут потребляться этим экземпляром IViewLocationExpander. Вычисленные значения используются для определения того, изменилось ли местоположение представления с момента его последнего нахождения.

параметры:

context: элемент ViewLocationExpanderContext для текущей операции расширения местоположения вида."

я посмотрел на некоторые классы, которые реализуют этот интерфейс-некоторые объявляют метод, но оставляют его пустым, другие реализуют его.

NonMainPageViewLocationExpander.cs:

public void PopulateValues(ViewLocationExpanderContext context)
{
}

LanguageViewLocationExpander.cs:

private const string ValueKey = "language";

public void PopulateValues(ViewLocationExpanderContext context)
{
    if (context == null)
    {
        throw new ArgumentNullException(nameof(context));
    }

    // Using CurrentUICulture so it loads the locale specific resources for the views.
#if NET451
    context.Values[ValueKey] = Thread.CurrentThread.CurrentUICulture.Name;
#else
    context.Values[ValueKey] = CultureInfo.CurrentUICulture.Name;
#endif
}

статьи "просмотр расширителя местоположения в ASP.NET ядро и MVC 6" приведен пример. Вот отрывок из объяснения:--23-->

вы можете добавить столько расширителей местоположения просмотра, сколько хотите. IViewLocationExpander интерфейс имеет 2 метода, PopulateValues и ExpandViewLocations. PopulateValues метод позволяет добавлять значения, которые позже могут быть использованы ExpandViewLocations метод. Значения, которые вы вводите в PopulateValues метод будет использоваться для поиска ключа кэша. ExpandViewLocations метод будет вызываться только в том случае, если нет результата кэша для ключа кэша или когда framework не может найти представление на кэшированный результат. В ExpandViewLocations метод, вы можете вернуть свои динамические местоположения просмотра. Теперь вы можете зарегистрировать этот расширитель местоположения вида в ,

services.Configure<RazorViewEngineOptions>(options =>
{
    options.ViewLocationExpanders.Add(new MyViewLocationExpander());
});

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