Add MetadataCollection

This commit is contained in:
Ryan Nowak 2017-10-25 23:46:15 -07:00
parent 812fa9599a
commit 81ddda7b96
6 changed files with 190 additions and 9 deletions

View File

@ -1,7 +1,6 @@
// 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.Diagnostics;
namespace Microsoft.AspNetCore.Dispatcher
@ -11,6 +10,6 @@ namespace Microsoft.AspNetCore.Dispatcher
{
public abstract string DisplayName { get; }
public abstract IReadOnlyList<object> Metadata { get; }
public abstract MetadataCollection Metadata { get; }
}
}

View File

@ -1,7 +1,6 @@
// 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.Diagnostics;
namespace Microsoft.AspNetCore.Dispatcher
@ -11,6 +10,6 @@ namespace Microsoft.AspNetCore.Dispatcher
{
public abstract string DisplayName { get; }
public abstract IReadOnlyList<object> Metadata { get; }
public abstract MetadataCollection Metadata { get; }
}
}

View File

@ -0,0 +1,104 @@
// 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;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.AspNetCore.Dispatcher
{
public class MetadataCollection : IReadOnlyList<object>
{
private readonly object[] _items;
public MetadataCollection()
{
_items = Array.Empty<object>();
}
public MetadataCollection(IEnumerable<object> items)
{
if (items == null)
{
throw new ArgumentNullException(nameof(items));
}
_items = items.ToArray();
}
public object this[int index] => _items[index];
public int Count => _items.Length;
public T GetMetadata<T>() where T : class
{
for (var i = _items.Length -1; i >= 0; i--)
{
var item = _items[i] as T;
if (item !=null)
{
return item;
}
}
return default;
}
public IEnumerable<T> GetOrderedMetadata<T>() where T : class
{
for (var i = 0; i < _items.Length; i++)
{
var item = _items[i] as T;
if (item != null)
{
yield return item;
}
}
}
public Enumerator GetEnumerator() => new Enumerator(this);
IEnumerator<object> IEnumerable<object>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public struct Enumerator : IEnumerator<object>
{
private object[] _items;
private int _index;
private object _current;
internal Enumerator(MetadataCollection collection)
{
_items = collection._items;
_index = 0;
_current = null;
}
public object Current => _current;
public void Dispose()
{
}
public bool MoveNext()
{
if (_index < _items.Length)
{
_current = _items[_index++];
return true;
}
_current = null;
return false;
}
public void Reset()
{
_index = 0;
_current = null;
}
}
}
}

View File

@ -29,12 +29,12 @@ namespace Microsoft.AspNetCore.Dispatcher
Template = template;
Defaults = new DispatcherValueCollection(values);
DisplayName = displayName;
Metadata = metadata.ToArray();
Metadata = new MetadataCollection(metadata);
}
public override string DisplayName { get; }
public override IReadOnlyList<object> Metadata { get; }
public override MetadataCollection Metadata { get; }
public string Template { get; }

View File

@ -78,7 +78,7 @@ namespace Microsoft.AspNetCore.Dispatcher
HttpMethod = httpMethod;
HandlerFactory = (next) => requestDelegate;
DisplayName = displayName;
Metadata = metadata.ToArray();
Metadata = new MetadataCollection(metadata);
}
public TemplateEndpoint(
@ -109,14 +109,14 @@ namespace Microsoft.AspNetCore.Dispatcher
HttpMethod = httpMethod;
HandlerFactory = delegateFactory;
DisplayName = displayName;
Metadata = metadata.ToArray();
Metadata = new MetadataCollection(metadata);
}
public override string DisplayName { get; }
public string HttpMethod { get; }
public override IReadOnlyList<object> Metadata { get; }
public override MetadataCollection Metadata { get; }
public Func<RequestDelegate, RequestDelegate> HandlerFactory { get; }

View File

@ -0,0 +1,79 @@
// 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.Linq;
using Xunit;
namespace Microsoft.AspNetCore.Dispatcher
{
public class MetadataCollectionTest
{
[Fact]
public void GetMetadata_ReturnsLastMatch()
{
// Arrange
var items = new object[]
{
new AuthNMetadata(),
new AuthZMetadata(),
new AuthNMetadata(),
};
var collection = new MetadataCollection(items);
// Act
var result = collection.GetMetadata<AuthNMetadata>();
// Assert
Assert.Same(items[2], result);
}
[Fact]
public void GetOrderedMetadata_ReturnsAllMatches()
{
// Arrange
var items = new object[]
{
new AuthNMetadata(),
new AuthZMetadata(),
new AuthNMetadata(),
};
var collection = new MetadataCollection(items);
// Act
var result = collection.GetOrderedMetadata<AuthNMetadata>();
// Assert
Assert.Equal(new object[] { items[0], items[2] }, result);
}
[Fact]
public void GetEnumerator_IncludesAllItems()
{
// Arrange
var items = new object[]
{
new AuthNMetadata(),
new AuthZMetadata(),
new AuthNMetadata(),
};
var collection = new MetadataCollection(items);
// Act
var result = collection.ToArray();
// Assert
Assert.Equal(items, result);
}
private class AuthNMetadata
{
}
private class AuthZMetadata
{
}
}
}