Transfer Service
✅ Similar to Blazor WebAssembly
Transfer service is a useful approach to share data between components in Blazor, especially when all of your components need to use the same data, also known as a "single source of truth". This approach allows you to centralize the data management and keep the state of your components consistent, making your application more maintainable and easier to test.
- Declare a transfer service
- Consume a transfer service
You can download the example code used in this topic on GitHub.
Declare a transfer service
A transfer service acts as a model, containing properties and events for each property.
To create a Transfer Service:
- Create a class and declare properties with events. For example:
public class ExampleTransferService
{
private string _data = "Blazor School";
public string Data
{
get => _data;
set
{
_data = value;
DataChanged?.Invoke(this, value);
}
}
public event EventHandler<string> DataChanged = (sender, value) => { };
}
In the code sample, we have Data
and ExampleInstances
as an example of a property and a collection. For collections, you can use ObservableCollection<T>
or create your own Collection<T>
class:
public class ExampleTransferService
{
public ObservableCollection<ExampleClass> ExampleInstances { get; set; } = new();
}
It's important to note that List<T>
does not support hooking events.
- Register the transfer service in the Program.cs file. For example:
...
builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddScoped<ExampleTransferService>();
By registering the Transfer Service class in the Program.cs, it can be injected into any component that needs it. This allows the components to share the same data and stay in sync with the state of the application.
Consume a transfer service
A transfer service can be consumed in both a component or a class. To consume a transfer service in a class, you need to inject the service into the constructor of your class and register it in the same way as the transfer service class. In this tutorial, we will focus on consuming a transfer service in a component.
Here's how to consume a transfer service in a component:
- Inject the transfer service and implement the
IDisposable
interface in the directive section of your component. For example:
@inject ExampleTransferService ExampleTransferService
@implements IDisposable
- Define methods to react to the change events in the code section of your component. The method signature must match the corresponding event. For example, if you want to react to the
DataChanged
event, which has EventHandler<string>
as the event handler, you need to have a method with the signature void MyMethod(object? sender, string value)
.
@code {
...
public void OnDataClassChanged(object? sender, string value)
{
InvokeAsync(StateHasChanged);
}
}
Or with for collection changes:
@code {
...
public void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs args)
{
InvokeAsync(StateHasChanged);
}
}
- Subscribe to the events in the Initialize phase and unsubscribe the subscribed events in the Dispose phase. See the Blazor Component Lifecycle guide for more information.
@code {
...
protected override void OnInitialized()
{
ExampleTransferService.ExampleInstances.CollectionChanged += OnCollectionChanged;
ExampleTransferService.DataChanged += OnDataClassChanged;
}
public void Dispose()
{
ExampleTransferService.ExampleInstances.CollectionChanged -= OnCollectionChanged;
ExampleTransferService.DataChanged -= OnDataClassChanged;
}
}