Skip to content

Instantly share code, notes, and snippets.

@pranavkm
Last active August 7, 2018 16:27
Show Gist options
  • Save pranavkm/10759ca15205c49e94ecd8739ae3a44a to your computer and use it in GitHub Desktop.
Save pranavkm/10759ca15205c49e94ecd8739ae3a44a to your computer and use it in GitHub Desktop.
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.Mvc
{
public class PollingActionDescriptorCollectionProvider : IActionDescriptorCollectionProvider
{
private readonly IActionDescriptorProvider[] _actionDescriptorProviders;
private readonly IActionDescriptorChangeProvider[] _actionDescriptorChangeProviders;
private ActionDescriptorCollection _collection;
private IChangeToken _changeToken;
private int _version = -1;
public PollingActionDescriptorCollectionProvider(
IEnumerable<IActionDescriptorProvider> actionDescriptorProviders,
IEnumerable<IActionDescriptorChangeProvider> actionDescriptorChangeProviders)
{
_actionDescriptorProviders = actionDescriptorProviders
.OrderBy(p => p.Order)
.ToArray();
_actionDescriptorChangeProviders = actionDescriptorChangeProviders.ToArray();
_changeToken = GetCompositeChangeToken();
}
private IChangeToken GetCompositeChangeToken()
{
if (_actionDescriptorChangeProviders.Length == 1)
{
return _actionDescriptorChangeProviders[0].GetChangeToken();
}
var changeTokens = new IChangeToken[_actionDescriptorChangeProviders.Length];
for (var i = 0; i < _actionDescriptorChangeProviders.Length; i++)
{
changeTokens[i] = _actionDescriptorChangeProviders[i].GetChangeToken();
}
return new CompositeChangeToken(changeTokens);
}
public ActionDescriptorCollection ActionDescriptors
{
get
{
if (_collection == null || _changeToken.HasChanged)
{
UpdateCollection();
_changeToken = GetCompositeChangeToken();
}
return _collection;
}
}
private void UpdateCollection()
{
var context = new ActionDescriptorProviderContext();
for (var i = 0; i < _actionDescriptorProviders.Length; i++)
{
_actionDescriptorProviders[i].OnProvidersExecuting(context);
}
for (var i = _actionDescriptorProviders.Length - 1; i >= 0; i--)
{
_actionDescriptorProviders[i].OnProvidersExecuted(context);
}
_collection = new ActionDescriptorCollection(
new ReadOnlyCollection<ActionDescriptor>(context.Results),
Interlocked.Increment(ref _version));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment