How to define and register custom services in Blazor WebAssembly

Key takeaways:

  • To define custom services, use dependency injection to create and manage custom services in Blazor WebAssembly, facilitating component communication.

  • Dependency injection has three components:

    • Client (which requires dependencies)

    • Service interface (defining required dependencies)

    • Service (providing the dependencies)

  • To manage service lifetimes effectively, choose between Singleton (one instance for the app), Scoped (new instance per request), or Transient (new instance per service request).

  • Implementation steps:

    • Define a service interface (e.g., IGreeterService).

    • Implement the service (e.g., MyGreeterService).

    • Register the service in the Program.cs using AddScoped, AddSingleton, or AddTransient.

    • Inject the service in components using the @inject directive for seamless use.

In Blazor WebAssembly, we can define and register custom services using the built-in dependency injection (DI) system. Blazor WebAssembly makes these services available throughout the application, sharing functionality and data between components.

Dependency injection (DI) in Blazor WebAssembly

Dependency injection is a pattern designed to help manage dependencies between different components or classes of an application. It is a way to decouple components from each other, making them easier to test, maintain, and modify. The DI pattern involves three main components:

  1. The component or class that requires dependencies (the client)
  2. The interface or abstract class that defines the dependencies required by the client
  3. The component or class that provides the dependencies (the service)

Lifespan for the services

Injected services can have different lifespans within the application. Here’s a breakdown of the options:

  • Singleton: Only one instance of the class is ever created and used throughout the application.
  • Scoped: A new class instance is created for each specific context (often called a scope). In web applications, a common scope is a single user request.
  • Transient: A brand new instance of the class is generated for every service request.

Here are the steps to define and register custom services in Blazor WebAssembly:

Steps to define and register custom services in Blazor WebAssembly
Steps to define and register custom services in Blazor WebAssembly

Example

In this example, the MyGreeterService implements the IGreeterService interface, which defines the Greet method. The MyGreeterService concatenates the name with a greeting and returns the result.

Steps to define and register custom services

Here are the steps to complete this example:

1. Define a service interface:

public interface IGreeterService
{
string Greet(string name);
}

We define the IGreeterService interface with one method signature, Greet, on line 3.

2. Implement the service:

public class MyGreeterService : IGreeterService
{
public string Greet(string myName)
{
return $"Hello, {myName}!";
}
}

We define a class MyGreeterService and inherit it from our service on line 1. This class implements the method Greet.

3. Register the service:

using Microsoft.Extensions.DependencyInjection;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
// Register the service with the DI container
builder.Services.AddScoped<IGreeterService, MyGreeterService>();
await builder.Build().RunAsync();

The next step is to register our service in the application builder. Here, we use the AddScoped method on line 7, which creates a new instance with each request.

Note: We can use AddSingleton and AddTransient for singleton and transient lifespan, respectively.

4. Use the service:

@page "/"
@using Microsoft.AspNetCore.Components
@using Microsoft.Extensions.DependencyInjection
@inject IGreeterService MyGreeterService
<h1>Greeting</h1>
<div>
@MyGreeterService.Greet("John")
</div>

Now, to use MyGreeterService, we need to inject the service into the component using the @inject keyword, as in line 5. Finally, we can use MyGreeterService in our application, as in line 9.

Explanation

The IGreeterService is registered with the DI container in the Program.cs file using the AddScoped method, which specifies that a new service instance will be instantiated for each scope.

Finally, in the component, IGreeterService is injected using the @inject directive, and the Greet method is called on the service instance to display the greeting.

Code example for custom services in Blazor WebAssembly

The following widget contains the complete code of the above example. Press the “RUN” button to execute it:

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.1" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.1" PrivateAssets="all" />
  </ItemGroup>

</Project>
Demo project

Conclusion

By leveraging dependency injection (DI) in Blazor WebAssembly, we can effectively manage the life cycle and sharing of functionalities between components. A well-designed DI system promotes loose coupling, improves testability, and simplifies code maintenance in Blazor WebAssembly applications.

Join our course on Building Real-Life Applications with Blazor WebAssembly to explore Blazor and its web development capabilities. You'll learn to create templated components, develop progressive web applications, harness JavaScript interoperability, etc. Elevate your skills and start building today!

Frequently asked questions

Haven’t found what you were looking for? Contact Us


What are the limitations of Blazor WebAssembly?

Following are some of the disadvantages of Blazor WebAssembly:

  • Limited browser support
  • Initial load time
  • Size of payload
  • Performance limitations

What is WebAssembly?

WebAssembly, abbreviated as Wasm, was developed by Microsoft in 2017. As the name suggests, it was introduced to bring assembly like functionality to web. It is a tool that enables web developers to deploy their applications written in any language other than JavaScript on the web. It is a compact binary instruction format for high-level languages such as C, C++, and Rust. Since WebAssembly is a low-level language, it runs at the native speed in the browser.


How can we use WebAssembly with JavaScript?

WebAssembly acts as a complementary addition used to improve the functionality of JavaScript execution on web browsers. To learn how to effectively use WebAssembly alongside JavaScript, check out our detailed Answer on using WebAssembly with JavaScript.


Free Resources

Copyright ©2025 Educative, Inc. All rights reserved