Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Mastering Blazor WebAssembly

You're reading from   Mastering Blazor WebAssembly A step-by-step guide to developing advanced single-page applications with Blazor WebAssembly

Arrow left icon
Product type Paperback
Published in Aug 2023
Publisher Packt
ISBN-13 9781803235103
Length 370 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Ahmad Mozaffar Ahmad Mozaffar
Author Profile Icon Ahmad Mozaffar
Ahmad Mozaffar
Arrow right icon
View More author details
Toc

Table of Contents (21) Chapters Close

Preface 1. Part 1: Blazor WebAssembly Essentials
2. Chapter 1: Understanding the Anatomy of a Blazor WebAssembly Project FREE CHAPTER 3. Chapter 2: Components in Blazor 4. Chapter 3: Developing Advanced Components in Blazor 5. Part 2: App Parts and Features
6. Chapter 4: Navigation and Routing 7. Chapter 5: Capturing User Input with Forms and Validation 8. Chapter 6: Consuming JavaScript in Blazor 9. Chapter 7: Managing Application State 10. Chapter 8: Consuming Web APIs from Blazor WebAssembly 11. Chapter 9: Authenticatiwng and Authorizing Users in Blazor 12. Chapter 10: Handling Errors in Blazor WebAssembly 13. Part 3: Optimization and Deployment
14. Chapter 11: Giving Your App a Speed Boost 15. Chapter 12: RenderTree in Blazor 16. Chapter 13: Testing Blazor WebAssembly Apps 17. Chapter 14: Publishing Blazor WebAssembly Apps 18. Chapter 15: What’s Next? 19. Index 20. Other Books You May Enjoy

Dependency injection in Blazor WebAssembly

Modern software development is all about scaling, separation, and testing, so when you write the code, you should feel confident about its behavior and reliability. To achieve that goal, you need to keep the SOLID principles in mind throughout your development journey. The principle represented by the letter D is dependency inversion. This basically refers to hiding the implementation of your services behind interfaces. For example, for each service class you have, you can create an interface that contains the methods of that class, and make the class implement the interface. Then, while consuming this service, you reference the interface instead of the class directly. This strategy decouples the components or code pieces that use a service from its implementation by depending on the service’s abstract layer, which is the interface.

All this is amazing, but there is one missing part: how to initialize the object of a service that will be used in more than one place. This is where DI comes into play. It’s simply a technique that allows you to register your services that are used in other services or components in a centralized container, and that container will be responsible for serving those objects to the components that require them.

How dependency injection works

The following diagram shows the flow of a ConsoleLoggingService class:

Figure 1.7 – The flow of the dependency injection container and associated services

Figure 1.7 – The flow of the dependency injection container and associated services

In the preceding figure, the ConsoleLoggingService class implements the ILoggingService interface. Then, in the DI container, we register an instance of ILoggingService with a new object of its implementation: ConsoleLoggingService. Whenever Component A requires logging logic, it uses ILoggingService (the abstraction layer of ConsoleLoggingService).

Instead of initializing a new object instance ourselves, the DI container is serving ILoggingService to Component A, which adds many benefits as it keeps the code separated. Further, the implementation logic for the full service could be changed at any time without touching Component A, which depends on the base interface of that service. For example, if we want to log the data to a server instead of the console to start using the new service, we can just write a new implementation of ILoggingService and register that instance in the DI container, without changing anything in Component A or any other client code.

Note

To learn more about the SOLID principles and software development, check out the following link: https://en.wikipedia.org/wiki/SOLID

Using dependency injection in Blazor WebAssembly

Blazor WebAssembly comes with a DI container out of the box. You can start by registering your services in the Program.cs file and then inject those services into the client components or services as well.

Let’s implement or write our first service, ILoggingService, as mentioned in the preceding section, with the Log method, and create an implementation to log the messages to the console window of the browser. Then, we will inject this service into the FetchData component and log the count of the weather data that the FetchData component gets. To implement the service, go through the following steps:

  1. In Solution Explorer, right-click on the project, and click on Add | New Folder. Name the folder Services.
Figure 1.8 – Adding a new folder through Solution Explorer

Figure 1.8 – Adding a new folder through Solution Explorer

  1. Right-click on the newly created folder and choose Add | New Item.
  2. From the dialog that shows up, choose Interface as the item type, and give it the name ILoggingService. Then click Add.
  3. The interface has been created, and the goal is to create the Log method. As you know, in the interfaces, we only define the signature of the method (its return data type and its parameter), so we will define that method as follows:
    public interface ILoggingService{     void Log(string message);}
  4. After creating the interface, we should create the implementation that logs that message to the console, so repeat step 2, but instead of creating an interface, let’s create a class and give it the name ConsoleLoggingService.
  5. After creating the class, let’s implement the ILoggingService interface and write the logic of that method as follows:
    public class ConsoleLoggingService : ILoggingService{    public void Log(string message)    {        Console.WriteLine(message);    }}

The Log method calls the WriteLine method in the Console class, but in Blazor WebAssembly the Console.WriteLine method doesn’t act the same as it does in other .NET apps by printing a string in a console app. It prints the string in the console window within the developer tools of the browser.

You can access the developer tools in your browser as follows:

  • Microsoft Edge: F12 in Windows or + + I for Mac
  • Other browsers: Ctrl + Shift + I

The last thing to get this service ready to be injected into other components is registering it in the DI container.

  1. Go to the Program.cs file and register the service using the AddScoped method:
    ...using BooksStore.Services;var builder = WebAssemblyHostBuilder.CreateDefault(args);...builder.Services.AddScoped<ILoggingService, ConsoleLoggingService>();await builder.Build().RunAsync();

Our first service right now is ready to be used and injected within any other components. The following example will show you how to inject this service in the FetchData component and achieve the required target of logging the count of weather forecast items to the console window of the browser:

  1. Open the _Imports.razor file and add a using statement to the Services namespaces:
    @using BooksStore.Services

We add references to the Services namespace in the imports because those services will mostly be used across many components, so we don’t have to add that using statement in every component.

Open the FetchData component in the Pages folder and inject ILoggingService by using the @inject Razor directive in the component:

@page "/fetchdata"...
@inject ILoggingService LoggingService
<PageTitle>Weather forecast</PageTitle>
<h1>Weather forecast</h1>
....
  1. Our service is ready to be used and we can call the Log function from the object instance in the C# code to log the count of the items as follows:
    ....        </tbody>    </table>}@code {    private WeatherForecast[]? forecasts;    protected override async Task OnInitializedAsync()    {        forecasts = await          Http.GetFromJsonAsync<WeatherForecast[]>           ("sample-data/weather.json");        LoggingService.Log($"Number of items retrieved                           is {forecasts.Count()}");    }    …

If you run the project and navigate to the Fetch data page after the data is retrieved, you can open the console window in your browser and you should see the message Number of items retrieved is 5.

Figure 1.9 – A screenshot of the console window with the printed sentence

Figure 1.9 – A screenshot of the console window with the printed sentence

Tip

To learn more about the DI concept in Blazor, you can check the following link: https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/dependency-injection?view=aspnetcore-7.0.

Now we have implemented a full cycle, from creating the service abstract layer to its implementation, registering the service in the DI container, and finally injecting and consuming that service from a separate component.

Learning about DI and how it works will help you understand many aspects of the application, such as writing maintainable, decoupled services. Also, you will be able to consume built-in services such as the HttpClient to make API calls and the IConfiguration service, which we are going to use in the next section to read and consume the application configurations.

You have been reading a chapter from
Mastering Blazor WebAssembly
Published in: Aug 2023
Publisher: Packt
ISBN-13: 9781803235103
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image