In Blazor WASM I have a service that has event property. I want to subscribe to this property immediately after the service is injected into component that is the used as a parent component(base class) for other child components.
Example:
public interface ISubService
{
event Action<bool> OnLoad;
}
public partial class ParentComponent : ComponentBase
{
}
There are several ways how to do it but none of them do what I want (except the hackish workaround at the end)
My options are:
Inject the service through
[Inject]
or@inject
and then useOnInitialized
orOnParameterSet
. Theoretically I can subscribe to the event in one of those methods but the main problem I have with this is that when a child component usesOnInitialized
orOnParameterSet
we have to remember to callbase.OnInitialized
orbase.OnParameterSet
(Error prone + more code)The second option was to inject the service through
[Inject]
or@inject
and then calling default constructor. This doesnt work because the constructor is called before those injected services are filled, so I cant access the eventInjecting it through Constructor (.NET9 DI) but this would require us to fill the base constructor everytime it is used inside the child component.
So my main requirement is that the registration logic is only inside the parent and is not propagated in any way into child components.
I was able to achieve this but it feels like hack-ish solution. I did this:
public partial class ParentComponent : ComponentBase
{
private ISubService? _subServiceHidden { get; set; }
[Inject] private ISubService _subService
{
get => _subServiceHidden!;
set
{
_subServiceHidden = value;
_subServiceHidden.OnLoad += HandleLoadingAction;
}
}
public void HandleLoadingAction(bool isLoading)
{
// Do something
}
}
This way the event is registered immediately after the service is filled and I dont have to adjust child components in any way.
So my questions are:
- Is it possible to do this in some "normal" way ? Or is this the current blazor limitation.
- Did you need anything like this in your usecases ?
In Blazor WASM I have a service that has event property. I want to subscribe to this property immediately after the service is injected into component that is the used as a parent component(base class) for other child components.
Example:
public interface ISubService
{
event Action<bool> OnLoad;
}
public partial class ParentComponent : ComponentBase
{
}
There are several ways how to do it but none of them do what I want (except the hackish workaround at the end)
My options are:
Inject the service through
[Inject]
or@inject
and then useOnInitialized
orOnParameterSet
. Theoretically I can subscribe to the event in one of those methods but the main problem I have with this is that when a child component usesOnInitialized
orOnParameterSet
we have to remember to callbase.OnInitialized
orbase.OnParameterSet
(Error prone + more code)The second option was to inject the service through
[Inject]
or@inject
and then calling default constructor. This doesnt work because the constructor is called before those injected services are filled, so I cant access the eventInjecting it through Constructor (.NET9 DI) but this would require us to fill the base constructor everytime it is used inside the child component.
So my main requirement is that the registration logic is only inside the parent and is not propagated in any way into child components.
I was able to achieve this but it feels like hack-ish solution. I did this:
public partial class ParentComponent : ComponentBase
{
private ISubService? _subServiceHidden { get; set; }
[Inject] private ISubService _subService
{
get => _subServiceHidden!;
set
{
_subServiceHidden = value;
_subServiceHidden.OnLoad += HandleLoadingAction;
}
}
public void HandleLoadingAction(bool isLoading)
{
// Do something
}
}
This way the event is registered immediately after the service is filled and I dont have to adjust child components in any way.
So my questions are:
- Is it possible to do this in some "normal" way ? Or is this the current blazor limitation.
- Did you need anything like this in your usecases ?
1 Answer
Reset to default 1Do the work in SetParametersAsync
.
The basic pattern to use is:
public override async Task SetParametersAsync(ParameterView parameters)
{
// Set the parameters immediately
parameters.SetParameterProperties(this);
//Do some sync or async work here
// it will all complete before the UI is rendered
await Task.Delay(TimeSpan.FromSeconds(1));
// run the normal lifecycle methods
// passing in an empty ParameterView. We've already set the parameters
await base.SetParametersAsync(ParameterView.Empty);
}
You can see the ComponentBase
code here - https://github/dotnet/aspnetcore/blob/caa429c49c4df4237d99c1c43e8b0e0faa8be9c5/src/Components/Components/src/ComponentBase.cs#L259