Контекст хелпера и получение зависимостей

Последнее обновление: 05.04.2022

Как и другие классы, tag-хелпер может получать зависимости, которые установлены в приложении с помощью механизма dependency injection.

Например, пусть у нас будут определены в проекте следующие сущности:

public interface ITimeService
{
    string GetTime();
}
public class SimpleTimeService : ITimeService
{
    public string GetTime() => System.DateTime.Now.ToString("HH:mm:ss");
}

Зарегистрируем сервис ITimeService в приложении в файле Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddTransient<ITimeService, SimpleTimeService>();

builder.Services.AddControllersWithViews();
var app = builder.Build();
app.MapControllerRoute(
	name: "default",
	pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

public interface ITimeService
{
    string GetTime();
}
public class SimpleTimeService : ITimeService
{
    public string GetTime() => DateTime.Now.ToString("HH:mm:ss");
}

Теперь мы можем получить сервис ITimeService в конструкторе класса тег-хелпера:

using Microsoft.AspNetCore.Razor.TagHelpers;

namespace MvcApp.TagHelpers
{
    public class TimerTagHelper : TagHelper
    {
        ITimeService timeService;
        public TimerTagHelper(ITimeService timeServ)
        {
            timeService = timeServ;
        }
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            output.TagName = "div";
            output.TagMode = TagMode.StartTagAndEndTag;
            output.Content.SetContent($"Текущее время: {timeService.GetTime()}");
        }
    }
}

Контекст представления

Кроме того, мы можем использовать получение зависимостей в виде свойств. Данная возможность предоставляется фреймворком MVC и доступна для ряда объектов, в том числе для объекта ViewContext, который представляет контекст представления, в котором используется tag-хелпер.

Используем ViewContext, изменив код хелпера следующим образом:

using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;

namespace MvcApp.TagHelpers
{
    public class TimerTagHelper : TagHelper
    {
        ITimeService timeService;

        [ViewContext]
        [HtmlAttributeNotBound]
        public ViewContext? ViewContext { get; set; }
        public TimerTagHelper(ITimeService timeServ)
        {
            timeService = timeServ;
        }
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            // получаем из строки запроса параметр font
            string? font = ViewContext?.HttpContext.Request.Query["font"];

            if (string.IsNullOrEmpty(font)) font = "Verdana";

            output.Attributes.SetAttribute("style", $"font-family:{font};font-size:18px;");
            output.TagName = "div";
            output.TagMode = TagMode.StartTagAndEndTag;
            output.Content.SetContent($"Текущее время: {timeService.GetTime()}");
        }
    }
}

С помощью следующего свойства ViewContext мы автоматически получаем контекст представления, в котором вызывается хелпер:

[ViewContext]
[HtmlAttributeNotBound]
public ViewContext? ViewContext { get; set; }

Чтобы автоматически получить данную зависимость, к свойству применяется атрибут [ViewContext].

Кроме того, здесь применяется атрибут HtmlAttributeNotBound. Так как по умолчанию публичные свойства tag-хелпера автоматически наполняются через атрибуты элементов, то может возникнуть ситуация, что в представлении для данного элемента будет определен атрибут view-context, например:

<timer view-context="@(new ViewContext())" />

Получив объект ViewContext, мы можем извлечь из него различную информацию. В частности, здесь получаем значение параметра font из строки запроса и это значение используем для установки шрифта элемента:

string? font = ViewContext?.HttpContext.Request.Query["font"];
if (string.IsNullOrEmpty(font)) font = "Verdana";
output.Attributes.SetAttribute("style", $"font-family:{font};font-size:18px;");

Далее остается определить тег-хелпер в представлении:

<timer />

И при выполнении запроса тег-хелпер получит параметр font из стоки запроса (если он указан) и использует его для установки семейства шрифта:

ViewContext в Tag Helper в ASP.NET Core MVC и C#
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850