Фреймворк Blazor позволяет воспользоваться систмой внедрения зависимостей, которая используется в ASP.NET Core и в целом в .NET. Рассомтрим только те моменты механизма DI, которые характерны именно для приложения Blazor. Пусть у нас есть следующий проект с одним компонентом App.razor и файлом TimeService.cs
В файле TimeService.cs определен одноименный сервис:
public interface ITimeService { string GetTime(); } public class TimeService : ITimeService { public string GetTime() => DateTime.Now.ToShortTimeString(); }
Класс TimeService представляет интерфейс ITimeService и реализует его метод GetTime(), который возвращает текущее время.
В главном файле программы - Program.cs добавим сервис ITimeService в коллекцию сервисов приложения:
using BlazorApp.Components; var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); // добавляем сервис TimeService builder.Services.AddTransient<ITimeService, TimeService>(); var app = builder.Build(); app.UseAntiforgery(); app.MapRazorComponents<App>() .AddInteractiveServerRenderMode(); app.Run();
Для установки сервисов через свойство Services
получаем коллекцию сервисов приложения - объект IServiceCollection. Далее
у него вызываем методы AddTransient/AddScoped/AddSingleton
для добавления сервиса. В данном случае посредством метода AddTransient
добавляем для
сервиса ITimeService в качестве реализации класс TimeService.
Для получения сервиса в компоненте применяется директива @inject. Например, получим сервис ITimeService в компоненте App:
@page "/" @inject ITimeService Timer <!DOCTYPE html> <html> <head> <title>METANIT.COM</title> <meta charset="utf-8" /> </head> <body> <h2>Time: @Timer.GetTime()</h2> <script src="_framework/blazor.web.js"></script> </body> </html>
После директивы @inject
указывается название сервиса (ITimeService), а затем название переменной (Timer), через которую можно получить реализацию сервиса.
@inject ITimeService Timer
Используя название переменной, можно обращаться к функциональности сервиса в коде компонента:
<h2>Time: @Timer.GetTime()</h2>
В итоге после запуска проекта на веб-странице в заголовке мы увидим текущее время, которое получено через сервис ITimeService:
Для получения сервисов в компоненте также можно использовать атрибут [Inject]. Этот атрибут применяется к свойству, в которое получаем сервис. Например, изменим компонент App следующим образом:
@page "/" <!DOCTYPE html> <html> <head> <title>METANIT.COM</title> <meta charset="utf-8" /> </head> <body> <h2>Time: @Timer.GetTime()</h2> <script src="_framework/blazor.web.js"></script> </body> </html> @code { [Inject] public required ITimeService Timer { get; set; } }
Поскольку к свойству Timer применяется атрибут [Inject]
, то значение для данного свойства будет обеспечивать система внедрения зависимостей. Поскольку это свойство
представляет ITimeService, то механиз DI будет искать в коллекции сервисов реализацию именно этого типа.
Если сервис предполагается использовать в другом сервисе, то один сервис может получить другой, как и вобще в .NET, через конструктор. Например, пусть у нас есть еще один сервис -
public class TimeFormatter { ITimeService timeService; public TimeFormatter(ITimeService timeService) { this.timeService = timeService; } public string FormatTime() => $"Current Time: {timeService.GetTime()}"; }
Он использует сервис ITimeService, который он получает через механизм DI через параметр конструктора.
В файле Program.cs оба сервиса добавляются в коллекцию сервисов приложения:
using BlazorApp.Components; var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); // добавляем сервисы builder.Services.AddTransient<ITimeService, TimeService>(); builder.Services.AddTransient<TimeFormatter>(); var app = builder.Build(); app.UseAntiforgery(); app.MapRazorComponents<App>() .AddInteractiveServerRenderMode(); app.Run();
В компоненте App также получим сервис TimeFormatter для рендеринга содержимого:
@page "/" @inject TimeFormatter Formatter <!DOCTYPE html> <html> <head> <title>METANIT.COM</title> <meta charset="utf-8" /> </head> <body> <h2>@Formatter.FormatTime()</h2> <script src="_framework/blazor.web.js"></script> </body> </html>
Ряд сервисов фреймворк Blazor предоставляет по умолчанию. Например, выведем все сервисы на консоль в файле Program.cs:
using BlazorApp.Components; var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); // добавляем сервисы builder.Services.AddTransient<ITimeService, TimeService>(); builder.Services.AddTransient<TimeFormatter>(); // выводим все сервисы на консоль foreach (var service in builder.Services) { Console.WriteLine(service.ServiceType); } var app = builder.Build(); app.UseAntiforgery(); app.MapRazorComponents<App>() .AddInteractiveServerRenderMode(); app.Run();