|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace Microsoft.AspNetCore.Mvc.Filters;
/// <summary>
/// A one-way cursor for filters.
/// </summary>
/// <remarks>
/// This will iterate the filter collection once per-stage, and skip any filters that don't have
/// the one of interfaces that applies to the current stage.
///
/// Filters are always executed in the following order, but short circuiting plays a role.
///
/// Indentation reflects nesting.
///
/// 1. Exception Filters
/// 2. Authorization Filters
/// 3. Action Filters
/// Action
///
/// 4. Result Filters
/// Result
///
/// </remarks>
internal struct FilterCursor
{
private readonly IFilterMetadata[] _filters;
private int _index;
public FilterCursor(IFilterMetadata[] filters)
{
_filters = filters;
_index = 0;
}
public void Reset()
{
_index = 0;
}
public FilterCursorItem<TFilter?, TFilterAsync?> GetNextFilter<TFilter, TFilterAsync>()
where TFilter : class
where TFilterAsync : class
{
while (_index < _filters.Length)
{
var filter = _filters[_index] as TFilter;
var filterAsync = _filters[_index] as TFilterAsync;
_index += 1;
if (filter != null || filterAsync != null)
{
return new FilterCursorItem<TFilter?, TFilterAsync?>(filter, filterAsync);
}
}
return default(FilterCursorItem<TFilter?, TFilterAsync?>);
}
}
|