// Copyright (c) Microsoft Open Technologies, Inc. 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.Reflection; using Microsoft.AspNet.Mvc.ModelBinding.Metadata; using Xunit; namespace Microsoft.AspNet.Mvc.ModelBinding { public class TestModelMetadataProvider : DefaultModelMetadataProvider { // Creates a provider with all the defaults - includes data annotations public static IModelMetadataProvider CreateDefaultProvider() { var detailsProviders = new IMetadataDetailsProvider[] { new DefaultBindingMetadataProvider(), new DataAnnotationsMetadataDetailsProvider(), }; var compositeDetailsProvider = new DefaultCompositeMetadataDetailsProvider(detailsProviders); return new DefaultModelMetadataProvider(compositeDetailsProvider); } private readonly TestModelMetadataDetailsProvider _detailsProvider; public TestModelMetadataProvider() : this(new TestModelMetadataDetailsProvider()) { } private TestModelMetadataProvider(TestModelMetadataDetailsProvider detailsProvider) : base(new DefaultCompositeMetadataDetailsProvider(new IMetadataDetailsProvider[] { new DefaultBindingMetadataProvider(), new DataAnnotationsMetadataDetailsProvider(), detailsProvider })) { _detailsProvider = detailsProvider; } public IMetadataBuilder ForType(Type type) { var key = ModelMetadataIdentity.ForType(type); var builder = new MetadataBuilder(key); _detailsProvider.Builders.Add(builder); return builder; } public IMetadataBuilder ForType() { return ForType(typeof(TModel)); } public IMetadataBuilder ForProperty(Type containerType, string propertyName) { var property = containerType.GetRuntimeProperty(propertyName); Assert.NotNull(property); var key = ModelMetadataIdentity.ForProperty(property.PropertyType, propertyName, containerType); var builder = new MetadataBuilder(key); _detailsProvider.Builders.Add(builder); return builder; } public IMetadataBuilder ForProperty(string propertyName) { return ForProperty(typeof(TContainer), propertyName); } private class TestModelMetadataDetailsProvider : IBindingMetadataProvider, IDisplayMetadataProvider, IValidationMetadataProvider { public List Builders { get; } = new List(); public void GetBindingMetadata(BindingMetadataProviderContext context) { foreach (var builder in Builders) { builder.Apply(context); } } public void GetDisplayMetadata(DisplayMetadataProviderContext context) { foreach (var builder in Builders) { builder.Apply(context); } } public void GetValidationMetadata(ValidationMetadataProviderContext context) { foreach (var builder in Builders) { builder.Apply(context); } } } public interface IMetadataBuilder { IMetadataBuilder BindingDetails(Action action); IMetadataBuilder DisplayDetails(Action action); IMetadataBuilder ValidationDetails(Action action); } private class MetadataBuilder : IMetadataBuilder { private List> _bindingActions = new List>(); private List> _displayActions = new List>(); private List> _valiationActions = new List>(); private readonly ModelMetadataIdentity _key; public MetadataBuilder(ModelMetadataIdentity key) { _key = key; } public void Apply(BindingMetadataProviderContext context) { if (_key.Equals(context.Key)) { foreach (var action in _bindingActions) { action(context.BindingMetadata); } } } public void Apply(DisplayMetadataProviderContext context) { if (_key.Equals(context.Key)) { foreach (var action in _displayActions) { action(context.DisplayMetadata); } } } public void Apply(ValidationMetadataProviderContext context) { if (_key.Equals(context.Key)) { foreach (var action in _valiationActions) { action(context.ValidationMetadata); } } } public IMetadataBuilder BindingDetails(Action action) { _bindingActions.Add(action); return this; } public IMetadataBuilder DisplayDetails(Action action) { _displayActions.Add(action); return this; } public IMetadataBuilder ValidationDetails(Action action) { _valiationActions.Add(action); return this; } } } }