Hi!
Today we will talk about how dependency injection works in blazor server. If you are familiar with dependency injection in asp.net core then there are no differences.
Dependency injection is configured in Startup.cs
at the root of the project. After creating the project, it will look like this
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
}
Let’s see what happens here.
services.AddRazorPages()
- adds razor pages support to the project
services.AddServerSideBlazor()
- adds blazor server support to the project
services.AddSingleton <WeatherForecastService>()
- registers the WeatherForecastService
class in DI.
WeatherForecastService
in the example is added as Singleton
. Other ways to add is Scoped
and Transient
. We will look at them in more detail below.
Let’s try to add a new class in DI and check how it works with different types (Singleton, Scoped, Transient).
To do this, in the Data
folder, create a file that will generate a random number.
using System;
namespace BlazorLearn.Data
{
public class RandomData
{
private readonly int randomData;
public RandomData()
{
Random random = new Random();
randomData = random.Next();
}
public int GetRandomData()
{
return randomData;
}
}
}
In the RandomData
class, a random number is generated in the constructor. And the GetRandomData
method returns it. In order to use a class in DI you need to create an interface. You can use it without interface. But thanks to the interface, you can easily replace this class with another implementation. This is how interface will look like.
namespace BlazorLearn.Data
{
public interface IRandomData
{
int GetRandomData();
}
}
Singleton
The class can now be registered in DI. Let’s start with Singleton. To do this in the Startup.cs
file in the method ConfigureServices
you need to add:
services.AddSingleton<IRandomData, RandomData>();
Now every time someone uses the IRandomData
interface, RandomData
will be called.
Now in index.razor
I will call the GetRandomNumber
method.
@page "/"
@using BlazorLearn.Data
@inject IRandomData RandomData
<h1>Hello, world!</h1>
Welcome to your new app.
Your random number is @RandomData.GetRandomData()
<SurveyPrompt Title="How is Blazor working for you?" />
@inject IRandomData RandomData
call constructor of our class.
Start application.
If I open the application in another browser or refresh page the random number will remain the same. This is how singleton works. The object is created once at the start of the application.
Scoped
Let’s see now how scoped works. Replace AddSingleton
with AddScoped
services.AddScoped<IRandomData, RandomData>();
And run the application. Now if I go to another page of the site and then go back the number will remain the same. But if I refresh the page, the number will change. Scoped objects are created once for each query.
Transient
And the last type is Transient
. Now replace AddScoped
with AddTransient
services.AddTransient<IRandomData, RandomData>();
Let’s run application. And now even if you switch from one tab to another the number changes every time.
DI in Class
Finally, let’s see how you can use the RandomData
class in another class with DI.
For example, take Data/WeatherForecastService.cs
. In this class you need to make a variable of type IRandomData
and initialize it in the constructor. And now it can be used anywhere in this class.
using System;
using System.Linq;
using System.Threading.Tasks;
namespace BlazorLearn.Data
{
public class WeatherForecastService
{
private IRandomData _randomData;
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
public WeatherForecastService(IRandomData randomData)
{
_randomData = randomData;
}
public Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
{
var rng = new Random();
return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = startDate.AddDays(index),
TemperatureC = _randomData.GetRandomData(),
Summary = Summaries[rng.Next(Summaries.Length)]
}).ToArray());
}
}
}
_randomData.GetRandomData()
result I will write in variable TemperatureC
.Start application again. And on the FetchData
page, the temperature will be generated using GetRandomData
.
It is important that DI WeatherForecastService
and RandomData
are added equally.
services.AddScoped<WeatherForecastService>();
services.AddScoped<IRandomData, RandomData>();