Dependency Injection
Dependency Injection (DI) is a technique that will decouple your code and make your website easy to maintain. In this guide, we will walk you through:
- What is DI?
- Creating a DI Service.
- Registering a service to
ServiceProvider
.
- Injecting a service into a component.
You can download the example code used in this topic on GitHub.
What is Dependency Injection?
Dependency Injection or DI is a technique that helps you remove the code to create an object. Instead of creating the object, you will get it from the repository. With that in mind, the DI in Blazor WebAssembly has been further improved. DI in Blazor WebAssembly is not only an object repository but also, each object has its own life time. Blazor WebAssembly will automatically dispose and create objects regarding its lifetime. The object that is in the repository is called service and the repository is called service provider. The following image illustrates the concept of DI.
Creating a DI Service
Any class can become a service. A service may not depend on any other service, which the service do not have a constructor. The following SimpleService
class is a standalone service.
public class SimpleService
{
public string Greeting(string name) => $"Greeting {name}";
}
If you need any other service, you can inject it in the constructor of the class as the following class NestedService
.
public class NestedService
{
private readonly SimpleService _simpleService;
public NestedService(SimpleService simpleService)
{
_simpleService = simpleService;
}
public string ServePeople() => $"{_simpleService.Greeting("customer")}, how can I help?";
}
The NestedService
depends on SimpleService
and therefore SimpleService
must not depend on NestedService
. The following code will make SimpleService
depends on NestedService
and will cause an error.
public SimpleService(NestedService nestedService) {} //This will make SimpleService depends on NestedService. Do not do this
In some cases, you will need static data like string
, int
, etc... You can also include it in the constructor. However, you will need to instruct ServiceProvider
how to create that particular service. Here is an example code of how to import static data to a service.
public class CustomizedConstructorService
{
private readonly string _resourceLocation;
private readonly SimpleService _simpleService;
public CustomizedConstructorService(string resourceLocation, SimpleService simpleService)
{
_resourceLocation = resourceLocation;
_simpleService = simpleService;
}
public string TellResourceLocation() => $"The resource location is {_resourceLocation}. {_simpleService.Greeting("Blazor School")}";
}
In rare cases, you will need multiple constructors. You will see how to set up this kind of service later on.
Registering a service to ServiceProvider
Once you have your service class, the next step would be to register it to the ServiceProvider
. Open Program.cs
and use the builder
variable to register the services.
var builder = WebAssemblyHostBuilder.CreateDefault(args);
...
builder.Services.AddSingleton<SimpleService>();
For services with static data in the constructor, you need to instruct ServiceProvider
on how to create that object. The following code demonstrates how to instruct ServiceProvider
to create CustomizedConstructorService
.
builder.Services.AddSingleton<CustomizedConstructorService>(sp => new("/wwwroot/resources", sp.GetRequiredService<SimpleService>()));
Injecting a service into a component
Once the service has been registered to the ServiceProvider
, you can inject it into another service like the demonstration at the previous section or inject it in a service. The following code demonstrates how to inject a service into a Razor Component.
@inject SimpleService SimpleService
<h3>@SimpleService.Greeting("Blazor School")</h3>