Skip to content

Commit e2b2df1

Browse files
pranavkmguardrex
authored andcommitted
Add a sample for circuit handler (dotnet#16702)
1 parent a226176 commit e2b2df1

File tree

1 file changed

+43
-10
lines changed

1 file changed

+43
-10
lines changed

aspnetcore/blazor/handle-errors.md

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Discover how ASP.NET Core Blazor how Blazor manages unhandled excep
55
monikerRange: '>= aspnetcore-3.1'
66
ms.author: riande
77
ms.custom: mvc
8-
ms.date: 12/18/2019
8+
ms.date: 01/22/2020
99
no-loc: [Blazor, SignalR]
1010
uid: blazor/handle-errors
1111
---
@@ -104,7 +104,7 @@ The preceding unhandled exceptions are described in the following sections of th
104104
When Blazor creates an instance of a component:
105105

106106
* The component's constructor is invoked.
107-
* The constructors of any non-singleton DI services supplied to the component's constructor via the [`@inject`](xref:blazor/dependency-injection#request-a-service-in-a-component) directive or the [`[Inject]`](xref:blazor/dependency-injection#request-a-service-in-a-component) attribute are invoked.
107+
* The constructors of any non-singleton DI services supplied to the component's constructor via the [`@inject`](xref:blazor/dependency-injection#request-a-service-in-a-component) directive or the [`[Inject]`](xref:blazor/dependency-injection#request-a-service-in-a-component) attribute are invoked.
108108

109109
A circuit fails when any executed constructor or a setter for any `[Inject]` property throws an unhandled exception. The exception is fatal because the framework can't instantiate the component. If constructor logic may throw exceptions, the app should trap the exceptions using a [try-catch](/dotnet/csharp/language-reference/keywords/try-catch) statement with error handling and logging.
110110

@@ -157,7 +157,7 @@ If user code doesn't trap and handle the exception, the framework logs the excep
157157

158158
### Component disposal
159159

160-
A component may be removed from the UI, for example, because the user has navigated to another page. When a component that implements <xref:System.IDisposable?displayProperty=fullName> is removed from the UI, the framework calls the component's <xref:System.IDisposable.Dispose*> method.
160+
A component may be removed from the UI, for example, because the user has navigated to another page. When a component that implements <xref:System.IDisposable?displayProperty=fullName> is removed from the UI, the framework calls the component's <xref:System.IDisposable.Dispose*> method.
161161

162162
If the component's `Dispose` method throws an unhandled exception, the exception is fatal to the circuit. If disposal logic may throw exceptions, the app should trap the exceptions using a [try-catch](/dotnet/csharp/language-reference/keywords/try-catch) statement with error handling and logging.
163163

@@ -184,16 +184,49 @@ For more information, see <xref:blazor/javascript-interop>.
184184

185185
### Circuit handlers
186186

187-
Blazor allows code to define a *circuit handler*, which receives notifications when the state of a user's circuit changes. The following states are used:
187+
Blazor Server allows code to define a *circuit handler*, which allows running code on changes to the state of a user's circuit. A circuit handler is implemented by deriving from <xref:Microsoft.AspNetCore.Components.Servers.Circuits.CircuitHandler /> and registering the class in the app's service container. The following example of a circuit handler tracks open SignalR connections:
188188

189-
* `initialized`
190-
* `connected`
191-
* `disconnected`
192-
* `disposed`
189+
```csharp
190+
using System.Collections.Generic;
191+
using System.Threading;
192+
using System.Threading.Tasks;
193+
using Microsoft.AspNetCore.Components.Server.Circuits;
193194

194-
Notifications are managed by registering a DI service that inherits from the `CircuitHandler` abstract base class.
195+
public class TrackingCircuitHandler : CircuitHandler
196+
{
197+
private HashSet<Circuit> _circuits = new HashSet<Circuit>();
195198

196-
If a custom circuit handler's methods throw an unhandled exception, the exception is fatal to the circuit. To tolerate exceptions in a handler's code or called methods, wrap the code in one or more [try-catch](/dotnet/csharp/language-reference/keywords/try-catch) statements with error handling and logging.
199+
public override Task OnConnectionUpAsync(Circuit circuit,
200+
CancellationToken cancellationToken)
201+
{
202+
_circuits.Add(circuit);
203+
204+
return Task.CompletedTask;
205+
}
206+
207+
public override Task OnConnectionDownAsync(Circuit circuit,
208+
CancellationToken cancellationToken)
209+
{
210+
_circuits.Remove(circuit);
211+
212+
return Task.CompletedTask;
213+
}
214+
215+
public int ConnectedCircuits => _circuits.Count;
216+
}
217+
```
218+
219+
Circuit handlers are registered using DI. Scoped instances are created per instance of a circuit. Using the `TrackingCircuitHandler` in the preceding example, a singleton service is created because the state of all circuits must be tracked:
220+
221+
```csharp
222+
public void ConfigureServices(IServiceCollection services)
223+
{
224+
...
225+
services.AddSingleton<CircuitHandler, TrackingCircuitHandler>();
226+
}
227+
```
228+
229+
If a custom circuit handler's methods throw an unhandled exception, the exception is fatal to the Blazor Server circuit. To tolerate exceptions in a handler's code or called methods, wrap the code in one or more [try-catch](/dotnet/csharp/language-reference/keywords/try-catch) statements with error handling and logging.
197230

198231
### Circuit disposal
199232

0 commit comments

Comments
 (0)