I have an IClipboardService
I was injecting into components, but as there is only ever one, I decided to try using a CascadingValue
instead.
I recreated all this in a minimal test case. Just add these changes to a basic WebAssembly Blazor app:
I created a CascadingClipboard.razor
component that looks like this
<CascadingValue Value="_clipboardService">
@ChildContent
</CascadingValue>
@inject ClipboardService _clipboardService
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}
I also created a far simpler test CascadingInt.razor
component with an int
value
<CascadingValue IsFixed=true Value="_int">
@ChildContent
</CascadingValue>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public int _int { get; set; } = 123;
}
I wrapped the MainLayout.razor with both:
@inherits LayoutComponentBase
<CascadingClipboard>
<CascadingInt>
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
</CascadingInt>
</CascadingClipboard>
Added receiving CascadingParameters
in Index.razor
@page "/"
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt Title="How is Blazor working for you?" />
@code{
[CascadingParameter]
public CascadingClipboard _cascadingClipboard { get; set; }
[CascadingParameter]
public int IntValue { get; set; }
protected override async Task OnParametersSetAsync()
{
// BREAKPOINT HERE TO CHECK VALUES
await base.OnParametersSetAsync();
}
}
The simple value is always present. The complex object is always null
.
I have tried using an explicit assignment instead of injection, but no difference.
Is this simply a limitation of Blazor CascadingValues?
More info:
The reason I tried this in the first place, is that my clipboard singleton needed to be initialised from local storage (to happily survive a refresh, or even returning later). Having a Cascading component makes that easy, but leaving the mechanics as a separate injectable service means I can still inject it into non-components (whereas Cascading only works with components). I now have a pattern for the best of both worlds.