Содержание
В предыдущей части мы познакомились с одним из способов получения зависимостей — с использованием директивы Razor @inject
. Способы получения зависимостей в Blazor Hybrid не ограничиваются только этой директивой и в этой части мы рассмотрим другие варианты.
Когда мы рассматривали вопросы, связанные с навигацией в Blazor Hybrid, то использовали один из доступных нам сервисов — NavigationManeger
. Рассмотрим на примере этого сервиса доступные нам способы получения зависимостей в Blazor Hybrid.
Внедрение через свойство (Property Injection)
Именно этот способ внедрения зависимостей мы использовали до сих пор. При этом, в зависимости от того, как реализован компонент Razor, мы можем использовать два вариант внедрения зависимости через конструктор.
Использование директивы @inject
Это уже известный нам способ, поэтому стоит только ещё раз повторить код:
@page "/" @inject NavigationManager Navigation <h1>Hello, world!</h1> Welcome to your new app. <button @onclick="NavigateToCounter">Счётчик</button> @code{ private void NavigateToCounter() { Navigation.NavigateTo("/counter"); } }
здесь сервис NavigationManager
внедряется через свойство Navigation
компонента Razor:
@inject NavigationManager Navigation
а директива @inject выглядит следующим образом:
@inject [Сервис] [Свойство]
где [Сервис]
— тип сервиса, который внедряется через свойство [Свойство]
. При этом, от нас не требуется явно определять свойство — компилятор создаст его самостоятельно и нам необходимо только им воспользоваться в коде C# компонента Razor.
Использование атрибута [Inject]
Этот способ используется в том случае, если для создания компонента Razor используется разделяемый класс. Например, создадим новое приложение Blazor Hybrid и используем разделяемый класс для компонента Home
. В обозревателе решений этот компонент будет выглядеть так:
Код класса
Home
будет выглядеть следующим образом:
using Microsoft.AspNetCore.Components; namespace BlazorDiLifetime.Components.Pages { public partial class Home : ComponentBase { } }
Внедрим NavigationManager
через новое свойство класса:
public partial class Home : ComponentBase { [Inject] public NavigationManager Navigation { get; set; } = default!; }
Здесь мы уже вручную создаем новое свойство с типом сервиса и определяем для этого свойства атрибут [Inject]
, который указывает, что значение свойства при инициализации должно быть получено из контейнера зависимостей.
Теперь добавим новый метод в класс:
public partial class Home : ComponentBase { [Inject] public NavigationManager Navigation { get; set; } = default!; public void NavigateToYandex() { if (Navigation != null) Navigation.NavigateTo("https://ya.ru"); } }
И внесем небольшие изменения в разметку компонента:
@page "/" <h1>Hello, world!</h1> Welcome to your new app. <button @onclick="NavigateToYandex">Перейти в Яндекс</button>
Теперь можно запустить приложение
и убедиться, что клик по кнопке открывает браузер и загружает страницу ya.ru, то есть сервис был успешно получен из контейнера зависимостей.
Внедрение через конструктор (Constructor Injection)
Внедрение через конструктор — это наиболее предпочтительный способ получения зависимостей в .NET. Однако, этот способ внедрения зависимостей не столь очевиден при работе с приложениями Blazor Hybrid так как сам шаблон приложения нас «подталкивает» на внедрение через свойство. Чтобы продемонстрировать внедрение через конструктор, изменим код нашего компонента Home
следующим образом:
public partial class Home : ComponentBase { private readonly NavigationManager navigation; public Home(NavigationManager navigation) { this.navigation = navigation; } public void NavigateToYandex() { navigation.NavigateTo("https://ya.ru"); } }
Здесь мы указываем в параметрах конструктора необходимые сервисы, которые необходимо получить из контейнера DI. Внедрение через конструктор может также применяется в том случае, если разрабатываемый сервис зависит от других сервисов. В этом случае механизм DI распознает то, какие зависимости необходимы для работы сервиса и создаст их при запросе сервиса.
Итого
В Blazor Hybrid мы можем использовать внедрение зависимостей через свойство (property injection) с использованием директивы Razor @inject
или атрибута [inject]
, а также через конструктор (constructor injection).