I have an AppState service which has the following:
public event Action OnDataChanged;
public MyObject CurrentObject { get; private set; }
public void UpdateMyObject(MyObject obj)
{
CurrentObject = obj;
OnDataChanged?.Invoke();
}
In one component, I call UpdateMyObject
. The AppState
service does get hit with the correct data, and OnDataChanged?.Invoke()
is called.
In another component, which is supposed to be subscribed to OnDataChanged
to make decisions on the data update, I have the following:
protected override void OnInitialized()
{
AppStateService.OnDataChanged = UpdateData;
}
private void UpdateData()
{
var data = AppStateService.CurrentObject;
}
I've tried to put breakpoints all over the 'listening' component, but nothing gets hit. Any ideas on what I'm doing wrong and why isn't UpdateData
method being called on OnChanged?.Invoke
from the state service? Suggestions on how to debug this?
CodePudding user response:
Here's my code that works - I built it in a Blazor Server template solution. I've made your object a string for simplicity.
public class AppState
{
public Guid Id { get; } = Guid.NewGuid();
public event Action? OnDataChanged;
// This is more normal for events
public event EventHandler? DataChanged;
public string? CurrentObject { get; private set; }
public void UpdateMyObject(string obj)
{
CurrentObject = obj;
OnDataChanged?.Invoke();
DataChanged?.Invoke(this, new EventArgs());
}
}
Service Registration
builder.Services.AddSingleton<WeatherForecastService>();
// Set as a singleton as the name suggests it's application specific and not user specific
builder.Services.AddSingleton<AppState>();
A component to display the state
// AppStateComponent.razor
@inject AppState AppStateService
@implements IDisposable
<h3>AppStateComponent</h3>
<div >
Service ID: @this.AppStateService.Id.ToString()
</div>
<div>
Data: @this.data
</div>
@code {
private string data = string.Empty;
protected override void OnInitialized()
{
this.AppStateService.OnDataChanged = UpdateData;
}
private void UpdateData()
{
data = this.AppStateService.CurrentObject!;
this.InvokeAsync(StateHasChanged);
}
public void Dispose()
{
this.AppStateService.OnDataChanged -= UpdateData;
}
}
And a test page
@page "/"
@inject AppState AppStateService
<div >
Service ID: @this.AppStateService.Id.ToString()
</div>
<AppStateComponent />
<div >
<button @onclick=UpdateData>Update</button>
</div>
@code {
private void UpdateData()
{
this.AppStateService.UpdateMyObject($"Updated at {DateTime.Now.ToLongTimeString()}");
}
}