Skip to content

Commit

Permalink
feat: improve BlazorCircuitContext.cs
Browse files Browse the repository at this point in the history
  • Loading branch information
alexyakunin committed Oct 23, 2023
1 parent ab5119a commit c228d79
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 22 deletions.
36 changes: 15 additions & 21 deletions src/Stl.Fusion.Blazor/BlazorCircuitContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,39 @@

namespace Stl.Fusion.Blazor;

public class BlazorCircuitContext : IDisposable
public class BlazorCircuitContext(IServiceProvider services) : ProcessorBase
{
private volatile int _isDisposing;
private static long _lastId;

private readonly TaskCompletionSource<Unit> _whenReady = TaskCompletionSourceExt.New<Unit>();
private volatile int _isPrerendering;
private ComponentBase? _rootComponent;
private Dispatcher? _dispatcher;
private ILogger? _log;

protected ILogger Log => _log ??= Services.LogFor(GetType());

public IServiceProvider Services { get; } = services;
public long Id { get; } = Interlocked.Increment(ref _lastId);
public Task WhenReady => _whenReady.Task;
public bool IsPrerendering => _isPrerendering != 0;
public bool IsDisposing => _isDisposing != 0;
public Dispatcher Dispatcher => _dispatcher ??= RootComponent.GetDispatcher();

public ComponentBase RootComponent {
get => _rootComponent ?? throw Errors.NotInitialized(nameof(RootComponent));
set {
if (_rootComponent == value)
return;
if (_rootComponent != null)
if (Interlocked.CompareExchange(ref _rootComponent, value, null) != null)
throw Errors.AlreadyInitialized(nameof(RootComponent));
_rootComponent = value;

_whenReady.TrySetResult(default);
}
}

public Dispatcher Dispatcher
=> RootComponent.GetDispatcher();

public ClosedDisposable<(BlazorCircuitContext, int)> Prerendering(bool isPrerendering = true)
{
var oldIsPrerendering = Interlocked.Exchange(ref _isPrerendering, isPrerendering ? 1 : 0);
return new ClosedDisposable<(BlazorCircuitContext Context, int OldIsPrerendering)>(
(this, oldIsPrerendering),
state => Interlocked.Exchange(ref state.Context._isPrerendering, state.OldIsPrerendering));
}

public void Dispose()
{
if (0 != Interlocked.CompareExchange(ref _isDisposing, 1, 0))
return;
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{ }
}
2 changes: 1 addition & 1 deletion src/Stl.Fusion.Blazor/FusionBlazorBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ internal FusionBlazorBuilder(
c.GetRequiredService<UIActionFailureTracker.Options>(), c));
services.TryAddScoped(c => new BlazorModeHelper(
c.GetRequiredService<NavigationManager>()));
services.TryAddScoped(_ => new BlazorCircuitContext());
services.TryAddScoped(c => new BlazorCircuitContext(c));
}
}

0 comments on commit c228d79

Please sign in to comment.