API-Review Strongly-typed collections for a few options types.

We don't want these extensions methods defined in a wierd namespace, it's
straightforward and future-proof to just make these strongly-typed
collections.
This commit is contained in:
Ryan Nowak 2015-09-20 22:10:08 -07:00
parent 895258d550
commit 9badd9386e
6 changed files with 80 additions and 106 deletions

View File

@ -1,43 +0,0 @@
// 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.Generic;
using Microsoft.AspNet.Mvc.ModelBinding.Validation;
namespace Microsoft.AspNet.Mvc
{
/// <summary>
/// Extensions for <see cref="IList{IExcludeTypeValidationFilter}"/>.
/// </summary>
public static class ExcludeTypeValidationFilterExtensions
{
/// <summary>
/// Adds a descriptor to the specified <paramref name="excludeTypeValidationFilters" /> that excludes the properties of
/// the <see cref="Type"/> specified and its derived types from validaton.
/// </summary>
/// <param name="excludeTypeValidationFilters">A list of <see cref="IExcludeTypeValidationFilter"/> which are used to
/// get a collection of exclude filters to be applied for filtering model properties during validation.
/// </param>
/// <param name="type"><see cref="Type"/> which should be excluded from validation.</param>
public static void Add(this IList<IExcludeTypeValidationFilter> excludeTypeValidationFilters, Type type)
{
var typeBasedExcludeFilter = new DefaultTypeBasedExcludeFilter(type);
excludeTypeValidationFilters.Add(typeBasedExcludeFilter);
}
/// <summary>
/// Adds a descriptor to the specified <paramref name="excludeTypeValidationFilters" /> that excludes the properties of
/// the type specified and its derived types from validaton.
/// </summary>
/// <param name="excludeTypeValidationFilters">A list of <see cref="IExcludeTypeValidationFilter"/> which are used to
/// get a collection of exclude filters to be applied for filtering model properties during validation.
/// </param>
/// <param name="typeFullName">Full name of the type which should be excluded from validation.</param>
public static void Add(this IList<IExcludeTypeValidationFilter> excludeTypeValidationFilters, string typeFullName)
{
var filter = new DefaultTypeNameBasedExcludeFilter(typeFullName);
excludeTypeValidationFilters.Add(filter);
}
}
}

View File

@ -1,110 +1,96 @@
// Copyright (c) .NET Foundation. All rights reserved.
// 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.Generic;
using System.Collections.ObjectModel;
using System.Reflection;
using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.Filters;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc
namespace Microsoft.AspNet.Mvc.Filters
{
/// <summary>
/// Extension methods for adding filters to the global filters collection.
/// </summary>
public static class FilterCollectionExtensions
public class FilterCollection : Collection<IFilterMetadata>
{
/// <summary>
/// Adds a type representing an <see cref="IFilterMetadata"/> to a filter collection.
/// Adds a type representing an <see cref="IFilterMetadata"/>.
/// </summary>
/// <param name="filters">A collection of <see cref="IFilterMetadata"/>.</param>
/// <param name="filterType">Type representing an <see cref="IFilterMetadata"/>.</param>
/// <returns>An <see cref="IFilterMetadata"/> representing the added type.</returns>
/// <remarks>
/// Filter instances will be created using
/// <see cref="Microsoft.Framework.DependencyInjection.ActivatorUtilities"/>.
/// Use <see cref="AddService(ICollection{IFilterMetadata}, Type)"/> to register a service as a filter.
/// Use <see cref="AddService(Type)"/> to register a service as a filter.
/// </remarks>
public static IFilterMetadata Add(
[NotNull] this ICollection<IFilterMetadata> filters,
[NotNull] Type filterType)
public IFilterMetadata Add([NotNull] Type filterType)
{
return Add(filters, filterType, order: 0);
return Add(filterType, order: 0);
}
/// <summary>
/// Adds a type representing an <see cref="IFilterMetadata"/> to a filter collection.
/// Adds a type representing an <see cref="IFilterMetadata"/>.
/// </summary>
/// <param name="filters">A collection of <see cref="IFilterMetadata"/>.</param>
/// <param name="filterType">Type representing an <see cref="IFilterMetadata"/>.</param>
/// <param name="order">The order of the added filter.</param>
/// <returns>An <see cref="IFilterMetadata"/> representing the added type.</returns>
/// <remarks>
/// Filter instances will be created using
/// <see cref="Microsoft.Framework.DependencyInjection.ActivatorUtilities"/>.
/// Use <see cref="AddService(ICollection{IFilterMetadata}, Type)"/> to register a service as a filter.
/// Use <see cref="AddService(Type)"/> to register a service as a filter.
/// </remarks>
public static IFilterMetadata Add(
[NotNull] this ICollection<IFilterMetadata> filters,
[NotNull] Type filterType,
int order)
public IFilterMetadata Add([NotNull] Type filterType, int order)
{
if (!typeof(IFilterMetadata).IsAssignableFrom(filterType))
{
var message = Resources.FormatTypeMustDeriveFromType(filterType.FullName, typeof(IFilterMetadata).FullName);
var message = Resources.FormatTypeMustDeriveFromType(
filterType.FullName,
typeof(IFilterMetadata).FullName);
throw new ArgumentException(message, nameof(filterType));
}
var filter = new TypeFilterAttribute(filterType) { Order = order };
filters.Add(filter);
Add(filter);
return filter;
}
/// <summary>
/// Adds a type representing an <see cref="IFilterMetadata"/> to a filter collection.
/// Adds a type representing an <see cref="IFilterMetadata"/>.
/// </summary>
/// <param name="filters">A collection of <see cref="IFilterMetadata"/>.</param>
/// <param name="filterType">Type representing an <see cref="IFilterMetadata"/>.</param>
/// <returns>An <see cref="IFilterMetadata"/> representing the added service type.</returns>
/// <remarks>
/// Filter instances will created through dependency injection. Use
/// <see cref="AddService(ICollection{IFilterMetadata}, Type)"/> to register a service that will be created via
/// <see cref="Add(Type)"/> to register a service that will be created via
/// type activation.
/// </remarks>
public static IFilterMetadata AddService(
[NotNull] this ICollection<IFilterMetadata> filters,
[NotNull] Type filterType)
public IFilterMetadata AddService([NotNull] Type filterType)
{
return AddService(filters, filterType, order: 0);
return AddService(filterType, order: 0);
}
/// <summary>
/// Adds a type representing an <see cref="IFilterMetadata"/> to a filter collection.
/// Adds a type representing an <see cref="IFilterMetadata"/>.
/// </summary>
/// <param name="filters">A collection of <see cref="IFilterMetadata"/>.</param>
/// <param name="filterType">Type representing an <see cref="IFilterMetadata"/>.</param>
/// <param name="order">The order of the added filter.</param>
/// <returns>An <see cref="IFilterMetadata"/> representing the added service type.</returns>
/// <remarks>
/// Filter instances will created through dependency injection. Use
/// <see cref="AddService(ICollection{IFilterMetadata}, Type)"/> to register a service that will be created via
/// <see cref="Add(Type)"/> to register a service that will be created via
/// type activation.
/// </remarks>
public static IFilterMetadata AddService(
[NotNull] this ICollection<IFilterMetadata> filters,
[NotNull] Type filterType,
int order)
public IFilterMetadata AddService([NotNull] Type filterType, int order)
{
if (!typeof(IFilterMetadata).GetTypeInfo().IsAssignableFrom(filterType.GetTypeInfo()))
{
var message = Resources.FormatTypeMustDeriveFromType(filterType.FullName, typeof(IFilterMetadata).FullName);
var message = Resources.FormatTypeMustDeriveFromType(
filterType.FullName,
typeof(IFilterMetadata).FullName);
throw new ArgumentException(message, nameof(filterType));
}
var filter = new ServiceFilterAttribute(filterType) { Order = order };
filters.Add(filter);
Add(filter);
return filter;
}
}
}
}

View File

@ -0,0 +1,34 @@
// 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.ObjectModel;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
{
public class ExcludeTypeValidationFilterCollection : Collection<IExcludeTypeValidationFilter>
{
/// <summary>
/// Adds an <see cref="IExcludeTypeValidationFilter"/> that excludes the properties of
/// the <see cref="Type"/> specified and its derived types from validaton.
/// </summary>
/// <param name="type"><see cref="Type"/> which should be excluded from validation.</param>
public void Add([NotNull] Type type)
{
var typeBasedExcludeFilter = new DefaultTypeBasedExcludeFilter(type);
Add(typeBasedExcludeFilter);
}
/// <summary>
/// Adds an <see cref="IExcludeTypeValidationFilter"/> that excludes the properties of
/// the <see cref="Type"/> specified and its derived types from validaton.
/// </summary>
/// <param name="typeFullName">Full name of the type which should be excluded from validation.</param>
public void Add([NotNull] string typeFullName)
{
var filter = new DefaultTypeNameBasedExcludeFilter(typeFullName);
Add(filter);
}
}
}

View File

@ -23,14 +23,14 @@ namespace Microsoft.AspNet.Mvc
{
CacheProfiles = new Dictionary<string, CacheProfile>(StringComparer.OrdinalIgnoreCase);
Conventions = new List<IApplicationModelConvention>();
Filters = new List<IFilterMetadata>();
Filters = new FilterCollection();
FormatterMappings = new FormatterMappings();
InputFormatters = new List<IInputFormatter>();
OutputFormatters = new List<IOutputFormatter>();
ModelBinders = new List<IModelBinder>();
ModelMetadataDetailsProviders = new List<IMetadataDetailsProvider>();
ModelValidatorProviders = new List<IModelValidatorProvider>();
ValidationExcludeFilters = new List<IExcludeTypeValidationFilter>();
ValidationExcludeFilters = new ExcludeTypeValidationFilterCollection();
ValueProviderFactories = new List<IValueProviderFactory>();
}
@ -47,10 +47,10 @@ namespace Microsoft.AspNet.Mvc
public IList<IApplicationModelConvention> Conventions { get; }
/// <summary>
/// Gets a list of <see cref="IFilterMetadata"/> which are used to construct filters that
/// Gets a collection of <see cref="IFilterMetadata"/> which are used to construct filters that
/// apply to all actions.
/// </summary>
public ICollection<IFilterMetadata> Filters { get; }
public FilterCollection Filters { get; }
/// <summary>
/// Used to specify mapping between the URL Format and corresponding
@ -118,9 +118,9 @@ namespace Microsoft.AspNet.Mvc
public bool RespectBrowserAcceptHeader { get; set; }
/// <summary>
/// Gets a list of <see cref="IExcludeTypeValidationFilter"/>s that are used by this application.
/// Gets a collection of <see cref="IExcludeTypeValidationFilter"/>s that are used by this application.
/// </summary>
public IList<IExcludeTypeValidationFilter> ValidationExcludeFilters { get; }
public ExcludeTypeValidationFilterCollection ValidationExcludeFilters { get; }
/// <summary>
/// Gets a list of <see cref="IValueProviderFactory"/> used by this application.

View File

@ -2,19 +2,17 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.ObjectModel;
using Microsoft.AspNet.Mvc.Filters;
using Xunit;
namespace Microsoft.AspNet.Mvc
namespace Microsoft.AspNet.Mvc.Filters
{
public class FilterCollectionExtensionsTest
public class FilterCollectionTest
{
[Fact]
public void Add_UsesTypeFilterAttribute()
{
// Arrange
var collection = new Collection<IFilterMetadata>();
var collection = new FilterCollection();
// Act
var added = collection.Add(typeof(MyFilter));
@ -29,7 +27,7 @@ namespace Microsoft.AspNet.Mvc
public void Add_WithOrder_SetsOrder()
{
// Arrange
var collection = new Collection<IFilterMetadata>();
var collection = new FilterCollection();
// Act
var added = collection.Add(typeof(MyFilter), 17);
@ -42,10 +40,10 @@ namespace Microsoft.AspNet.Mvc
public void Add_ThrowsOnNonIFilter()
{
// Arrange
var collection = new Collection<IFilterMetadata>();
var collection = new FilterCollection();
var expectedMessage =
"The type 'Microsoft.AspNet.Mvc.FilterCollectionExtensionsTest+NonFilter' must derive from " +
$"The type '{typeof(NonFilter).FullName}' must derive from " +
$"'{typeof(IFilterMetadata).FullName}'." + Environment.NewLine +
"Parameter name: filterType";
@ -60,7 +58,7 @@ namespace Microsoft.AspNet.Mvc
public void AddService_UsesServiceFilterAttribute()
{
// Arrange
var collection = new Collection<IFilterMetadata>();
var collection = new FilterCollection();
// Act
var added = collection.AddService(typeof(MyFilter));
@ -75,7 +73,7 @@ namespace Microsoft.AspNet.Mvc
public void AddService_SetsOrder()
{
// Arrange
var collection = new Collection<IFilterMetadata>();
var collection = new FilterCollection();
// Act
var added = collection.AddService(typeof(MyFilter), 17);
@ -88,10 +86,10 @@ namespace Microsoft.AspNet.Mvc
public void AddService_ThrowsOnNonIFilter()
{
// Arrange
var collection = new Collection<IFilterMetadata>();
var collection = new FilterCollection();
var expectedMessage =
"The type 'Microsoft.AspNet.Mvc.FilterCollectionExtensionsTest+NonFilter' must derive from " +
$"The type '{typeof(NonFilter).FullName}' must derive from " +
$"'{typeof(IFilterMetadata).FullName}'." + Environment.NewLine +
"Parameter name: filterType";

View File

@ -1,20 +1,19 @@
// 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 Microsoft.AspNet.Mvc.ModelBinding.Validation;
using Xunit;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
public class ExcludeTypeValidationFilterExtensionsTests
public class ExcludeTypeValidationFilterCollectionTest
{
[Fact]
public void AddFilter_ByType()
{
// Arrange
var type = typeof(BaseType);
var collection = new List<IExcludeTypeValidationFilter>();
var collection = new ExcludeTypeValidationFilterCollection();
// Act
collection.Add(type);
@ -29,7 +28,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{
// Arrange
var type = typeof(BaseType);
var collection = new List<IExcludeTypeValidationFilter>();
var collection = new ExcludeTypeValidationFilterCollection();
// Act
collection.Add(type.FullName);