Reputation: 5042
I'm working on a new application and I opted to go with Blazor Server Side. I have the existing backend setup and am trying to replace the UI project only. I have a registry for all the services and this registry is used in both API and Blazor UI project:
public class DependencyContainer
{
public static void RegisterServices(IServiceCollection services)
{
#region Domain InMemoryBus MediatR
services.AddScoped<IMediatorHandler, InMemoryBus>();
#endregion
#region Domain Handlers
services.AddScoped<IRequestHandler<RadarCreateCommand, bool>, RadarProjectCommandHandler>();
#endregion
#region Application Layer
services.AddScoped<IRadarProjectService, RadarProjectService>();
//services.AddScoped<IContactService, ContactService>();
//services.AddScoped<ICategoryService, CategoryService>();
//services.AddScoped<ISubCategoryService, SubCategoryService>();
#endregion
#region Infrastructure/Data Layer
services.AddScoped<IPlaygroundBiRepository, PlaygroundBiRepository>();
//services.AddScoped<IContactRepository, ContactRepository>();
//services.AddScoped<ICategoryRepository, CategoryRepository>();
//services.AddScoped<ISubCategoryRepository, SubCategoryRepository>();
services.AddScoped<DesignTrackerContext>();
services.AddScoped<PlaygroundBiContext>();
#endregion
}
}
In my Blazor project, I have the reference to the registry project and am calling this method in 'Startup.cs' as:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
...
services.AddMediatR(typeof(Startup));
services.RegisterAutoMapper();
RegisterServices(services);
}
Now, on my page, I want to show a list of Projects. There is a service that will expose all projects non-entity POCOs. The page is setup like so:
@page "/projects"
@using DesignTracker.Application.Interfaces
@using DesignTracker.Application.ViewModels
<div class="container-fluid">
<div class="row my-4">
<div class="col-12">
<TelerikGrid Data="@allProjects" Height="550px" FilterMode="@GridFilterMode.FilterMenu"
Sortable="true" Pageable="true" PageSize="20" Groupable="true"
EditMode="@GridEditMode.Inline">
<GridColumns>
<GridColumn Field="Id" Title="Id" Width="100px" Editable="false" Groupable="false" />
<GridColumn Field="Date">
<Template>
@((context as RadarProjectViewModel).LastUpdateTime?.ToString("dddd, dd MMM yyyy"))
</Template>
</GridColumn>
<GridColumn Field="Name" />
<GridColumn Field="Department" />
<GridColumn Field="Summary" />
<GridCommandColumn>
<GridCommandButton Command="Save" Icon="@IconName.Save" ShowInEdit="true">Update</GridCommandButton>
<GridCommandButton Command="Edit" Icon="@IconName.Edit" Primary="true">Edit</GridCommandButton>
<GridCommandButton Command="Delete" Icon="@IconName.Delete">Delete</GridCommandButton>
<GridCommandButton Command="Cancel" Icon="@IconName.Cancel" ShowInEdit="true">Cancel</GridCommandButton>
</GridCommandColumn>
</GridColumns>
<GridToolBar>
<GridCommandButton Command="Add" Icon="@IconName.Plus" Primary="true">Add Project</GridCommandButton>
</GridToolBar>
</TelerikGrid>
</div>
</div>
</div>
@code {
private readonly IRadarProjectService _service;
private IEnumerable<RadarProjectViewModel> allProjects;
}
If I follow the WeatherService example that is shipping with Blazor templates, I do not see IoC in action because there is a method that is called in the OnInitializedAsync()
that actually initializes the forecasts:
List<WeatherForecast> forecasts { get; set; }
protected override async Task OnInitializedAsync()
{
await GetForecasts();
}
async Task GetForecasts()
{
forecasts = await ForecastService.GetForecastListAsync(DateTime.Now);
}
From my MVC and Asp.Net Core experience, all I needed to do was create backing interfaces for the services I required and create a loaded constructor and the DI engine would inject the initialized objects at runtime.
How is this possible in Blazor's code{ ... }
?
Upvotes: 1
Views: 1095
Reputation: 5404
To apply dependency injection directly on the blazor page use @inject
directive.
.razor
page:
@page "/"
@using YourServiceNamespace
@inject IYourService yourService // Here injecting dependency
<div>/*some html here*/</div>
@code
{
public string[] ArrayOfStrings => yourService.GetArrayOfStrings();
}
Startup.cs
file:
services.AddScoped<IYourService, YourService>();
Blazor will automatically receive your service from application environment and injects it directly into page so you can use it like from plain csharp code.
Upvotes: 4