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. Singletone

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.

Scoped

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. Transient

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. RandomData

It is important that DI WeatherForecastService and RandomData are added equally.

            services.AddScoped<WeatherForecastService>();
            services.AddScoped<IRandomData, RandomData>();