54 lines
1.8 KiB
C#
54 lines
1.8 KiB
C#
// Copyright (c) .NET Foundation. All rights reserved.
|
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.Primitives;
|
|
|
|
namespace Microsoft.AspNetCore.Routing.TestObjects
|
|
{
|
|
public class DynamicEndpointDataSource : EndpointDataSource
|
|
{
|
|
private readonly List<Endpoint> _endpoints;
|
|
private CancellationTokenSource _cts;
|
|
private CancellationChangeToken _changeToken;
|
|
private readonly object _lock;
|
|
|
|
public DynamicEndpointDataSource(params Endpoint[] endpoints)
|
|
{
|
|
_endpoints = new List<Endpoint>();
|
|
_endpoints.AddRange(endpoints);
|
|
_lock = new object();
|
|
|
|
CreateChangeToken();
|
|
}
|
|
|
|
public override IChangeToken GetChangeToken() => _changeToken;
|
|
|
|
public override IReadOnlyList<Endpoint> Endpoints => _endpoints;
|
|
|
|
// Trigger change
|
|
public void AddEndpoint(Endpoint endpoint)
|
|
{
|
|
_endpoints.Add(endpoint);
|
|
|
|
// Capture the old tokens so that we can raise the callbacks on them. This is important so that
|
|
// consumers do not register callbacks on an inflight event causing a stackoverflow.
|
|
var oldTokenSource = _cts;
|
|
var oldToken = _changeToken;
|
|
|
|
CreateChangeToken();
|
|
|
|
// Raise consumer callbacks. Any new callback registration would happen on the new token
|
|
// created in earlier step.
|
|
oldTokenSource.Cancel();
|
|
}
|
|
|
|
private void CreateChangeToken()
|
|
{
|
|
_cts = new CancellationTokenSource();
|
|
_changeToken = new CancellationChangeToken(_cts.Token);
|
|
}
|
|
}
|
|
} |