diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs index bf7afa4b91..f3ccae757c 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Internal; +using Microsoft.Framework.OptionsModel; using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Mvc @@ -115,7 +116,8 @@ private IOutputFormatter SelectFormatter(ObjectResult objectResult, OutputFormat .ActionContext .HttpContext .RequestServices - .GetRequiredService() + .GetRequiredService>() + .Options .OutputFormatters .OfType() .ToArray(); diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ObjectResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ObjectResult.cs index fabce23584..135f94161d 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ObjectResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ObjectResult.cs @@ -273,10 +273,12 @@ private IEnumerable GetDefaultFormatters(ActionContext context IEnumerable formatters = null; if (Formatters == null || Formatters.Count == 0) { - formatters = context.HttpContext - .RequestServices - .GetRequiredService() - .OutputFormatters; + formatters = context + .HttpContext + .RequestServices + .GetRequiredService>() + .Options + .OutputFormatters; } else { diff --git a/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvoker.cs b/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvoker.cs index 391b8ff3c0..efa26b64b4 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvoker.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvoker.cs @@ -23,20 +23,20 @@ public ControllerActionInvoker( [NotNull] IReadOnlyList filterProviders, [NotNull] IControllerFactory controllerFactory, [NotNull] ControllerActionDescriptor descriptor, - [NotNull] IInputFormattersProvider inputFormatterProvider, + [NotNull] IReadOnlyList inputFormatters, [NotNull] IControllerActionArgumentBinder controllerActionArgumentBinder, - [NotNull] IModelBinderProvider modelBinderProvider, - [NotNull] IModelValidatorProviderProvider modelValidatorProviderProvider, - [NotNull] IValueProviderFactoryProvider valueProviderFactoryProvider, + [NotNull] IReadOnlyList modelBinders, + [NotNull] IReadOnlyList modelValidatorProviders, + [NotNull] IReadOnlyList valueProviderFactories, [NotNull] IScopedInstance actionBindingContextAccessor, [NotNull] ITempDataDictionary tempData) : base( actionContext, filterProviders, - inputFormatterProvider, - modelBinderProvider, - modelValidatorProviderProvider, - valueProviderFactoryProvider, + inputFormatters, + modelBinders, + modelValidatorProviders, + valueProviderFactories, actionBindingContextAccessor) { _descriptor = descriptor; diff --git a/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvokerProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvokerProvider.cs index 2e2497808d..d99a8881ff 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvokerProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvokerProvider.cs @@ -6,6 +6,7 @@ using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.Internal; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Mvc.Core { @@ -14,31 +15,28 @@ public class ControllerActionInvokerProvider : IActionInvokerProvider private readonly IControllerActionArgumentBinder _argumentBinder; private readonly IControllerFactory _controllerFactory; private readonly IFilterProvider[] _filterProviders; - private readonly IInputFormattersProvider _inputFormattersProvider; - private readonly IModelBinderProvider _modelBinderProvider; - private readonly IModelValidatorProviderProvider _modelValidationProviderProvider; - private readonly IValueProviderFactoryProvider _valueProviderFactoryProvider; + private readonly IReadOnlyList _inputFormatters; + private readonly IReadOnlyList _modelBinders; + private readonly IReadOnlyList _modelValidatorProviders; + private readonly IReadOnlyList _valueProviderFactories; private readonly IScopedInstance _actionBindingContextAccessor; private readonly ITempDataDictionary _tempData; public ControllerActionInvokerProvider( IControllerFactory controllerFactory, - IInputFormattersProvider inputFormattersProvider, IEnumerable filterProviders, IControllerActionArgumentBinder argumentBinder, - IModelBinderProvider modelBinderProvider, - IModelValidatorProviderProvider modelValidationProviderProvider, - IValueProviderFactoryProvider valueProviderFactoryProvider, + IOptions optionsAccessor, IScopedInstance actionBindingContextAccessor, ITempDataDictionary tempData) { _controllerFactory = controllerFactory; - _inputFormattersProvider = inputFormattersProvider; _filterProviders = filterProviders.OrderBy(item => item.Order).ToArray(); _argumentBinder = argumentBinder; - _modelBinderProvider = modelBinderProvider; - _modelValidationProviderProvider = modelValidationProviderProvider; - _valueProviderFactoryProvider = valueProviderFactoryProvider; + _inputFormatters = optionsAccessor.Options.InputFormatters.ToArray(); + _modelBinders = optionsAccessor.Options.ModelBinders.ToArray(); + _modelValidatorProviders = optionsAccessor.Options.ModelValidatorProviders.ToArray(); + _valueProviderFactories = optionsAccessor.Options.ValueProviderFactories.ToArray(); _actionBindingContextAccessor = actionBindingContextAccessor; _tempData = tempData; } @@ -60,11 +58,11 @@ public void OnProvidersExecuting([NotNull] ActionInvokerProviderContext context) _filterProviders, _controllerFactory, actionDescriptor, - _inputFormattersProvider, + _inputFormatters, _argumentBinder, - _modelBinderProvider, - _modelValidationProviderProvider, - _valueProviderFactoryProvider, + _modelBinders, + _modelValidatorProviders, + _valueProviderFactories, _actionBindingContextAccessor, _tempData); } diff --git a/src/Microsoft.AspNet.Mvc.Core/DefaultControllerActionArgumentBinder.cs b/src/Microsoft.AspNet.Mvc.Core/DefaultControllerActionArgumentBinder.cs index fe58ab5523..93b3b51743 100644 --- a/src/Microsoft.AspNet.Mvc.Core/DefaultControllerActionArgumentBinder.cs +++ b/src/Microsoft.AspNet.Mvc.Core/DefaultControllerActionArgumentBinder.cs @@ -4,11 +4,9 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.ModelBinding; -using Microsoft.AspNet.Mvc.ModelBinding.Metadata; using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.Internal; using Microsoft.Framework.OptionsModel; @@ -37,7 +35,7 @@ public DefaultControllerActionArgumentBinder( public async Task> BindActionArgumentsAsync( ActionContext actionContext, - ActionBindingContext actionBindingContext, + ActionBindingContext actionBindingContext, object controller) { var actionDescriptor = actionContext.ActionDescriptor as ControllerActionDescriptor; @@ -66,7 +64,7 @@ await PopulateArgumentsAsync( actionArguments, actionDescriptor.Parameters); return actionArguments; - } + } private void ActivateProperties(object controller, Type containerType, Dictionary properties) { diff --git a/src/Microsoft.AspNet.Mvc.Core/Description/DefaultApiDescriptionProvider.cs b/src/Microsoft.AspNet.Mvc.Core/Description/DefaultApiDescriptionProvider.cs index 31139637fa..852c2b87f8 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Description/DefaultApiDescriptionProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Description/DefaultApiDescriptionProvider.cs @@ -11,6 +11,7 @@ using Microsoft.AspNet.Routing; using Microsoft.AspNet.Routing.Template; using Microsoft.Framework.Internal; +using Microsoft.Framework.OptionsModel; using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Mvc.Description @@ -21,21 +22,23 @@ namespace Microsoft.AspNet.Mvc.Description /// public class DefaultApiDescriptionProvider : IApiDescriptionProvider { - private readonly IOutputFormattersProvider _formattersProvider; + private readonly IList _outputFormatters; private readonly IModelMetadataProvider _modelMetadataProvider; private readonly IInlineConstraintResolver _constraintResolver; /// /// Creates a new instance of . /// - /// The . + /// The accessor for . + /// The used for resolving inline + /// constraints. /// The . public DefaultApiDescriptionProvider( - IOutputFormattersProvider formattersProvider, + IOptions optionsAccessor, IInlineConstraintResolver constraintResolver, IModelMetadataProvider modelMetadataProvider) { - _formattersProvider = formattersProvider; + _outputFormatters = optionsAccessor.Options.OutputFormatters; _constraintResolver = constraintResolver; _modelMetadataProvider = modelMetadataProvider; } @@ -316,10 +319,9 @@ private IReadOnlyList GetResponseFormats( contentTypes.Add(null); } - var formatters = _formattersProvider.OutputFormatters; foreach (var contentType in contentTypes) { - foreach (var formatter in formatters) + foreach (var formatter in _outputFormatters) { var responseFormatMetadataProvider = formatter as IApiResponseFormatMetadataProvider; if (responseFormatMetadataProvider != null) diff --git a/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs b/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs index de38bde056..1f01eb1d14 100644 --- a/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs +++ b/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs @@ -16,10 +16,11 @@ namespace Microsoft.AspNet.Mvc.Core public abstract class FilterActionInvoker : IActionInvoker { private readonly IReadOnlyList _filterProviders; - private readonly IInputFormattersProvider _inputFormatterProvider; - private readonly IModelBinderProvider _modelBinderProvider; - private readonly IModelValidatorProviderProvider _modelValidatorProviderProvider; - private readonly IValueProviderFactoryProvider _valueProviderFactoryProvider; + private readonly IReadOnlyList _inputFormatters; + private readonly IReadOnlyList _modelBinders; + private readonly IReadOnlyList _modelValidatorProviders; + private readonly IReadOnlyList _valueProviderFactories; + private readonly IScopedInstance _actionBindingContextAccessor; private IFilter[] _filters; @@ -41,19 +42,19 @@ public abstract class FilterActionInvoker : IActionInvoker public FilterActionInvoker( [NotNull] ActionContext actionContext, [NotNull] IReadOnlyList filterProviders, - [NotNull] IInputFormattersProvider inputFormatterProvider, - [NotNull] IModelBinderProvider modelBinderProvider, - [NotNull] IModelValidatorProviderProvider modelValidatorProviderProvider, - [NotNull] IValueProviderFactoryProvider valueProviderFactoryProvider, + [NotNull] IReadOnlyList inputFormatters, + [NotNull] IReadOnlyList modelBinders, + [NotNull] IReadOnlyList modelValidatorProviders, + [NotNull] IReadOnlyList valueProviderFactories, [NotNull] IScopedInstance actionBindingContextAccessor) { ActionContext = actionContext; _filterProviders = filterProviders; - _inputFormatterProvider = inputFormatterProvider; - _modelBinderProvider = modelBinderProvider; - _modelValidatorProviderProvider = modelValidatorProviderProvider; - _valueProviderFactoryProvider = valueProviderFactoryProvider; + _inputFormatters = inputFormatters; + _modelBinders = modelBinders; + _modelValidatorProviders = modelValidatorProviders; + _valueProviderFactories = valueProviderFactories; _actionBindingContextAccessor = actionBindingContextAccessor; } @@ -206,14 +207,10 @@ private async Task InvokeAllResourceFiltersAsync() var context = new ResourceExecutingContext(ActionContext, _filters); - context.InputFormatters = new List(_inputFormatterProvider.InputFormatters); - context.ModelBinders = new List(_modelBinderProvider.ModelBinders); - - context.ValidatorProviders = new List( - _modelValidatorProviderProvider.ModelValidatorProviders); - - context.ValueProviderFactories = new List( - _valueProviderFactoryProvider.ValueProviderFactories); + context.InputFormatters = new List(_inputFormatters); + context.ModelBinders = new List(_modelBinders); + context.ValidatorProviders = new List(_modelValidatorProviders); + context.ValueProviderFactories = new List(_valueProviderFactories); _resourceExecutingContext = context; await InvokeResourceFilterAsync(); diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNoContentOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNoContentOutputFormatter.cs index 4b9f752f2a..5e0f2a52da 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNoContentOutputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNoContentOutputFormatter.cs @@ -1,8 +1,6 @@ // 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.Threading.Tasks; using Microsoft.AspNet.WebUtilities; using Microsoft.Net.Http.Headers; diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNotAcceptableOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNotAcceptableOutputFormatter.cs index 298f6f2516..fda0195214 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNotAcceptableOutputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNotAcceptableOutputFormatter.cs @@ -1,8 +1,6 @@ // 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.Threading.Tasks; using Microsoft.AspNet.WebUtilities; using Microsoft.Net.Http.Headers; diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/IJsonOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/IJsonOutputFormatter.cs index cc07f4c437..10516814c8 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/IJsonOutputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/IJsonOutputFormatter.cs @@ -8,7 +8,7 @@ namespace Microsoft.AspNet.Mvc /// /// /// The class filter the collection of - /// and use only those which implement + /// and use only those which implement /// . /// /// To create a custom formatter that can be used by , derive from diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinders/BodyModelBinder.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinders/BodyModelBinder.cs index 0d9d7aa7da..fdb1cf6c78 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinders/BodyModelBinder.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinders/BodyModelBinder.cs @@ -6,8 +6,6 @@ using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.Core; -using Microsoft.AspNet.Mvc.ModelBinding; -using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Internal; @@ -19,39 +17,25 @@ namespace Microsoft.AspNet.Mvc.ModelBinding /// public class BodyModelBinder : BindingSourceModelBinder { - private readonly ActionContext _actionContext; - private readonly IScopedInstance _bindingContext; - private readonly IInputFormatterSelector _formatterSelector; - private readonly IValidationExcludeFiltersProvider _bodyValidationExcludeFiltersProvider; - /// /// Creates a new . /// - /// An accessor to the . - /// An accessor to the . - /// The . - /// - /// The . - /// - public BodyModelBinder([NotNull] IScopedInstance context, - [NotNull] IScopedInstance bindingContext, - [NotNull] IInputFormatterSelector selector, - [NotNull] IValidationExcludeFiltersProvider bodyValidationExcludeFiltersProvider) + public BodyModelBinder() : base(BindingSource.Body) { - _actionContext = context.Value; - _bindingContext = bindingContext; - _formatterSelector = selector; - _bodyValidationExcludeFiltersProvider = bodyValidationExcludeFiltersProvider; } /// protected async override Task BindModelCoreAsync([NotNull] ModelBindingContext bindingContext) { - var formatters = _bindingContext.Value.InputFormatters; + var requestServices = bindingContext.OperationBindingContext.HttpContext.RequestServices; + + var formatterSelector = requestServices.GetRequiredService(); + var actionContext = requestServices.GetRequiredService>().Value; + var formatters = requestServices.GetRequiredService>().Value.InputFormatters; - var formatterContext = new InputFormatterContext(_actionContext, bindingContext.ModelType); - var formatter = _formatterSelector.SelectFormatter(formatters.ToList(), formatterContext); + var formatterContext = new InputFormatterContext(actionContext, bindingContext.ModelType); + var formatter = formatterSelector.SelectFormatter(formatters.ToList(), formatterContext); if (formatter == null) { diff --git a/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs b/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs index 86a4a7f8c4..19f1453b35 100644 --- a/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs +++ b/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs @@ -5,9 +5,9 @@ using System.Collections.Generic; using Microsoft.AspNet.Mvc.ApplicationModels; using Microsoft.AspNet.Mvc.Core; -using Microsoft.AspNet.Mvc.OptionDescriptors; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding.Metadata; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; namespace Microsoft.AspNet.Mvc { @@ -22,16 +22,16 @@ public class MvcOptions public MvcOptions() { Conventions = new List(); - ModelBinders = new List(); + ModelBinders = new List(); ViewEngines = new List(); - ValueProviderFactories = new List(); - OutputFormatters = new List(); - InputFormatters = new List(); + ValueProviderFactories = new List(); + OutputFormatters = new List(); + InputFormatters = new List(); Filters = new List(); FormatterMappings = new FormatterMappings(); - ValidationExcludeFilters = new List(); + ValidationExcludeFilters = new List(); ModelMetadataDetailsProviders = new List(); - ModelValidatorProviders = new List(); + ModelValidatorProviders = new List(); CacheProfiles = new Dictionary(StringComparer.OrdinalIgnoreCase); } @@ -68,25 +68,23 @@ public AntiForgeryOptions AntiForgeryOptions /// Gets a list of which are used to construct filters that /// apply to all actions. /// - public ICollection Filters { get; private set; } + public ICollection Filters { get; } /// - /// Gets a list of the which are used to construct - /// a list of by . + /// Gets a list of s that are used by this application. /// - public IList OutputFormatters { get; } + public IList OutputFormatters { get; } /// - /// Gets a list of the which are used to construct - /// a list of by . + /// Gets a list of s that are used by this application. /// - public IList InputFormatters { get; } + public IList InputFormatters { get; } /// - /// Gets a list of which are used to construct a list - /// of exclude filters by . + /// Gets a list of s that are used by this application. /// - public IList ValidationExcludeFilters { get; } + public IList ValidationExcludeFilters { get; } + = new List(); /// /// Gets or sets the maximum number of validation errors that are allowed by this application before further @@ -107,17 +105,14 @@ public int MaxModelValidationErrors } /// - /// Get a list of the used by the - /// Gets a list of the used by the - /// . + /// Gets a list of s used by this application. /// - public IList ModelBinders { get; } + public IList ModelBinders { get; } /// - /// Gets a list of the s used by - /// . + /// Gets a list of s used by this application. /// - public IList ModelValidatorProviders { get; } + public IList ModelValidatorProviders { get; } /// /// Gets a list of descriptors that represent used @@ -126,10 +121,9 @@ public int MaxModelValidationErrors public IList ViewEngines { get; } /// - /// Gets a list of descriptors that represent - /// used by this application. + /// Gets a list of used by this application. /// - public IList ValueProviderFactories { get; } + public IList ValueProviderFactories { get; } /// /// Gets a list of instances that will be applied to diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/ViewEngine/CompositeViewEngine.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/ViewEngine/CompositeViewEngine.cs index f0f302dc3d..efc5caf7bb 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/ViewEngine/CompositeViewEngine.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/ViewEngine/CompositeViewEngine.cs @@ -1,24 +1,55 @@ // 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.Linq; using Microsoft.Framework.Internal; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Mvc.Rendering { /// public class CompositeViewEngine : ICompositeViewEngine { - public CompositeViewEngine(IViewEngineProvider viewEngineProvider) + /// + /// Initializes a new instance of . + /// + /// The options accessor for . + /// As instance that creates + /// an instance of type . + /// A instance that retrieves services from the + /// service collection. + public CompositeViewEngine( + IOptions optionsAccessor, + ITypeActivatorCache typeActivatorCache, + IServiceProvider serviceProvider) { - ViewEngines = viewEngineProvider.ViewEngines; + var viewEngines = new List(); + foreach (var descriptor in optionsAccessor.Options.ViewEngines) + { + IViewEngine viewEngine; + if (descriptor.ViewEngine != null) + { + viewEngine = descriptor.ViewEngine; + } + else + { + viewEngine = typeActivatorCache.CreateInstance( + serviceProvider, + descriptor.ViewEngineType); + } + + viewEngines.Add(viewEngine); + } + + ViewEngines = viewEngines; } /// - /// Gets the list of ViewEngines the CompositeViewEngine delegates to. + /// Gets the list of this instance of delegates to. /// - public IReadOnlyList ViewEngines { get; private set; } + public IReadOnlyList ViewEngines { get; } /// public ViewEngineResult FindPartialView([NotNull] ActionContext context, diff --git a/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ViewEngineDescriptor.cs b/src/Microsoft.AspNet.Mvc.Core/ViewEngineDescriptor.cs similarity index 54% rename from src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ViewEngineDescriptor.cs rename to src/Microsoft.AspNet.Mvc.Core/ViewEngineDescriptor.cs index f74c123cc7..d026acf554 100644 --- a/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ViewEngineDescriptor.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewEngineDescriptor.cs @@ -2,23 +2,30 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.OptionDescriptors +namespace Microsoft.AspNet.Mvc { /// /// Encapsulates information that describes an . /// - public class ViewEngineDescriptor : OptionDescriptor + public class ViewEngineDescriptor { /// /// Creates a new instance of . /// /// The type that the descriptor represents. public ViewEngineDescriptor([NotNull] Type type) - : base(type) { + if (!typeof(IViewEngine).IsAssignableFrom(type)) + { + var message = Resources.FormatTypeMustDeriveFromType(type.FullName, typeof(IViewEngine).FullName); + throw new ArgumentException(message, nameof(type)); + } + + ViewEngineType = type; } /// @@ -26,8 +33,19 @@ public ViewEngineDescriptor([NotNull] Type type) /// /// An instance of that the descriptor represents. public ViewEngineDescriptor([NotNull] IViewEngine viewEngine) - : base(viewEngine) { + ViewEngine = viewEngine; + ViewEngineType = viewEngine.GetType(); } + + /// + /// Gets the type of the described by this . + /// + public Type ViewEngineType { get; } + + /// + /// Gets the instance described by this . + /// + public IViewEngine ViewEngine { get; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/BinderMetadata/ModelBinderAttribute.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/BinderMetadata/ModelBinderAttribute.cs index bd94966bdb..45770cea6c 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/BinderMetadata/ModelBinderAttribute.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/BinderMetadata/ModelBinderAttribute.cs @@ -41,14 +41,12 @@ public Type BinderType { if (value != null) { - if (!typeof(IModelBinder).IsAssignableFrom(value) && - !typeof(IModelBinderProvider).IsAssignableFrom(value)) + if (!typeof(IModelBinder).IsAssignableFrom(value)) { throw new InvalidOperationException( - Resources.FormatBinderType_MustBeIModelBinderOrIModelBinderProvider( + Resources.FormatBinderType_MustBeIModelBinder( value.FullName, - typeof(IModelBinder).FullName, - typeof(IModelBinderProvider).FullName)); + typeof(IModelBinder).FullName)); } } diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/BinderTypeBasedModelBinder.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/BinderTypeBasedModelBinder.cs index 6eb0710762..bebadda706 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/BinderTypeBasedModelBinder.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/BinderTypeBasedModelBinder.cs @@ -17,10 +17,9 @@ public class BinderTypeBasedModelBinder : IModelBinder { private readonly Func _createFactory = (t) => ActivatorUtilities.CreateFactory(t, Type.EmptyTypes); - private ConcurrentDictionary _typeActivatorCache = + private readonly ConcurrentDictionary _typeActivatorCache = new ConcurrentDictionary(); - public async Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext.BinderType == null) @@ -37,19 +36,10 @@ public async Task BindModelAsync(ModelBindingContext binding var modelBinder = instance as IModelBinder; if (modelBinder == null) { - var modelBinderProvider = instance as IModelBinderProvider; - if (modelBinderProvider != null) - { - modelBinder = new CompositeModelBinder(modelBinderProvider.ModelBinders); - } - else - { - throw new InvalidOperationException( - Resources.FormatBinderType_MustBeIModelBinderOrIModelBinderProvider( - bindingContext.BinderType.FullName, - typeof(IModelBinder).FullName, - typeof(IModelBinderProvider).FullName)); - } + throw new InvalidOperationException( + Resources.FormatBinderType_MustBeIModelBinder( + bindingContext.BinderType.FullName, + typeof(IModelBinder).FullName)); } var result = await modelBinder.BindModelAsync(bindingContext); diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinders/ServicesModelBinder.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/ServicesModelBinder.cs similarity index 100% rename from src/Microsoft.AspNet.Mvc.Core/ModelBinders/ServicesModelBinder.cs rename to src/Microsoft.AspNet.Mvc.ModelBinding/Binders/ServicesModelBinder.cs diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Properties/Resources.Designer.cs index b4bd26fbbb..44ed02e8f1 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Properties/Resources.Designer.cs @@ -459,19 +459,19 @@ internal static string FormatModelStateDictionary_MaxModelStateErrors() } /// - /// The type '{0}' must implement either '{1}' or '{2}' to be used as a model binder. + /// The type '{0}' must implement '{1}' to be used as a model binder. /// - internal static string BinderType_MustBeIModelBinderOrIModelBinderProvider + internal static string BinderType_MustBeIModelBinder { - get { return GetString("BinderType_MustBeIModelBinderOrIModelBinderProvider"); } + get { return GetString("BinderType_MustBeIModelBinder"); } } /// - /// The type '{0}' must implement either '{1}' or '{2}' to be used as a model binder. + /// The type '{0}' must implement '{1}' to be used as a model binder. /// - internal static string FormatBinderType_MustBeIModelBinderOrIModelBinderProvider(object p0, object p1, object p2) + internal static string FormatBinderType_MustBeIModelBinder(object p0, object p1) { - return string.Format(CultureInfo.CurrentCulture, GetString("BinderType_MustBeIModelBinderOrIModelBinderProvider"), p0, p1, p2); + return string.Format(CultureInfo.CurrentCulture, GetString("BinderType_MustBeIModelBinder"), p0, p1); } /// diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Resources.resx b/src/Microsoft.AspNet.Mvc.ModelBinding/Resources.resx index d1104cd28e..0654d7794a 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Resources.resx +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Resources.resx @@ -201,8 +201,8 @@ The maximum number of allowed model errors has been reached. - - The type '{0}' must implement either '{1}' or '{2}' to be used as a model binder. + + The type '{0}' must implement '{1}' to be used as a model binder. The value '{0}' is not valid for {1}. diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultObjectValidator.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultObjectValidator.cs index 8f46da0fe5..f54ecadba8 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultObjectValidator.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultObjectValidator.cs @@ -17,15 +17,21 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation /// public class DefaultObjectValidator : IObjectModelValidator { - private readonly IValidationExcludeFiltersProvider _excludeFilterProvider; + private readonly IList _excludeFilters; private readonly IModelMetadataProvider _modelMetadataProvider; - + + /// + /// Initializes a new instance of . + /// + /// s that determine + /// types to exclude from validation. + /// The . public DefaultObjectValidator( - IValidationExcludeFiltersProvider excludeFilterProvider, - IModelMetadataProvider modelMetadataProvider) + [NotNull] IList excludeFilters, + [NotNull] IModelMetadataProvider modelMetadataProvider) { - _excludeFilterProvider = excludeFilterProvider; _modelMetadataProvider = modelMetadataProvider; + _excludeFilters = excludeFilters; } /// @@ -39,13 +45,13 @@ public void Validate([NotNull] ModelValidationContext modelValidationContext) ValidateNonVisitedNodeAndChildren( modelValidationContext.RootPrefix, - validationContext, + validationContext, validators: null); } private bool ValidateNonVisitedNodeAndChildren( string modelKey, - ValidationContext validationContext, + ValidationContext validationContext, IList validators) { var modelValidationContext = validationContext.ModelValidationContext; @@ -98,7 +104,7 @@ private bool ValidateNonVisitedNodeAndChildren( // We don't need to recursively traverse the graph for types that shouldn't be validated var modelType = modelExplorer.Model.GetType(); - if (IsTypeExcludedFromValidation(_excludeFilterProvider.ExcludeFilters, modelType)) + if (IsTypeExcludedFromValidation(_excludeFilters, modelType)) { var result = ShallowValidate(modelKey, modelExplorer, validationContext, validators); MarkPropertiesAsSkipped(modelKey, modelExplorer.Metadata, validationContext); @@ -146,7 +152,7 @@ private void MarkPropertiesAsSkipped(string currentModelKey, ModelMetadata metad if (fieldValidationState != ModelValidationState.Unvalidated) { return; - } + } foreach (var childMetadata in metadata.Properties) { @@ -182,7 +188,7 @@ private bool ValidateProperties( var propertyBindingName = propertyMetadata.BinderModelName ?? propertyMetadata.PropertyName; var childKey = ModelBindingHelper.CreatePropertyModelName(currentModelKey, propertyBindingName); if (!ValidateNonVisitedNodeAndChildren( - childKey, + childKey, propertyValidationContext, validators: null)) { @@ -300,14 +306,8 @@ private static bool ShallowValidate( return isValid; } - private bool IsTypeExcludedFromValidation(IReadOnlyList filters, Type type) + private bool IsTypeExcludedFromValidation(IList filters, Type type) { - // This can be set to null in ModelBinding scenarios which does not flow through this path. - if (filters == null) - { - return false; - } - return filters.Any(filter => filter.IsTypeExcluded(type)); } diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultTypeBasedExcludeFilter.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultTypeBasedExcludeFilter.cs similarity index 93% rename from src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultTypeBasedExcludeFilter.cs rename to src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultTypeBasedExcludeFilter.cs index 86dac927c5..b8d50e03c4 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultTypeBasedExcludeFilter.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultTypeBasedExcludeFilter.cs @@ -2,10 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { /// /// Provides an implementation of which can filter diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultTypeNameBasedExcludeFilter.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultTypeNameBasedExcludeFilter.cs similarity index 95% rename from src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultTypeNameBasedExcludeFilter.cs rename to src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultTypeNameBasedExcludeFilter.cs index 25be7d9272..cccb27a847 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultTypeNameBasedExcludeFilter.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultTypeNameBasedExcludeFilter.cs @@ -2,10 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { /// /// Provides an implementation of which can filter diff --git a/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs index fee66c9588..8a4691f31e 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs @@ -219,7 +219,7 @@ internal static string FormatRazorPage_MethodCannotBeCalled(object p0) } /// - /// {0} has not been called for the page '{1}'. + /// {0} has not been called for the page at '{1}'. /// internal static string RenderBodyNotCalled { @@ -227,7 +227,7 @@ internal static string RenderBodyNotCalled } /// - /// {0} has not been called for the page '{1}'. + /// {0} has not been called for the page at '{1}'. /// internal static string FormatRenderBodyNotCalled(object p0, object p1) { @@ -283,7 +283,7 @@ internal static string FormatSectionNotDefined(object p0) } /// - /// The following sections have been defined but have not been rendered for the page '{0}': '{1}'. + /// The following sections have been defined but have not been rendered by the page at '{0}': '{1}'. /// internal static string SectionsNotRendered { @@ -291,7 +291,7 @@ internal static string SectionsNotRendered } /// - /// The following sections have been defined but have not been rendered for the page '{0}': '{1}'. + /// The following sections have been defined but have not been rendered by the page at '{0}': '{1}'. /// internal static string FormatSectionsNotRendered(object p0, object p1) { diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorViewEngine.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorViewEngine.cs index b6dc4c0381..75317a0444 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/RazorViewEngine.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/RazorViewEngine.cs @@ -6,10 +6,9 @@ using System.Diagnostics; using System.Globalization; using System.Linq; -using Microsoft.AspNet.Mvc.Razor.Internal; -using Microsoft.AspNet.Mvc.Razor.OptionDescriptors; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.Framework.Internal; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Mvc.Razor { @@ -41,7 +40,7 @@ public class RazorViewEngine : IRazorViewEngine private readonly IRazorPageFactory _pageFactory; private readonly IRazorViewFactory _viewFactory; - private readonly IReadOnlyList _viewLocationExpanders; + private readonly IList _viewLocationExpanders; private readonly IViewLocationCache _viewLocationCache; /// @@ -50,12 +49,12 @@ public class RazorViewEngine : IRazorViewEngine /// The page factory used for creating instances. public RazorViewEngine(IRazorPageFactory pageFactory, IRazorViewFactory viewFactory, - IViewLocationExpanderProvider viewLocationExpanderProvider, + IOptions optionsAccessor, IViewLocationCache viewLocationCache) { _pageFactory = pageFactory; _viewFactory = viewFactory; - _viewLocationExpanders = viewLocationExpanderProvider.ViewLocationExpanders; + _viewLocationExpanders = optionsAccessor.Options.ViewLocationExpanders; _viewLocationCache = viewLocationCache; } diff --git a/src/Microsoft.AspNet.Mvc.Razor/OptionDescriptors/RazorViewEngineOptions.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorViewEngineOptions.cs similarity index 73% rename from src/Microsoft.AspNet.Mvc.Razor/OptionDescriptors/RazorViewEngineOptions.cs rename to src/Microsoft.AspNet.Mvc.Razor/RazorViewEngineOptions.cs index e906a8b483..6a505a24fa 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/OptionDescriptors/RazorViewEngineOptions.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/RazorViewEngineOptions.cs @@ -4,23 +4,21 @@ using System; using System.Collections.Generic; using Microsoft.AspNet.FileProviders; -using Microsoft.AspNet.Mvc.Razor.OptionDescriptors; namespace Microsoft.AspNet.Mvc.Razor { /// - /// Provides programmatic configuration for the default . + /// Provides programmatic configuration for the . /// public class RazorViewEngineOptions { private IFileProvider _fileProvider; /// - /// Get a of descriptors for s used by this - /// application. + /// Get a used by the . /// - public IList ViewLocationExpanders { get; } - = new List(); + public IList ViewLocationExpanders { get; } + = new List(); /// /// Gets or sets the used by to locate Razor files on diff --git a/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs b/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs index 8423865cfb..e057662157 100644 --- a/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs +++ b/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs @@ -32,7 +32,7 @@ public static void ConfigureMvc(MvcOptions options) // Set up ModelBinding options.ModelBinders.Add(new BinderTypeBasedModelBinder()); options.ModelBinders.Add(new ServicesModelBinder()); - options.ModelBinders.Add(typeof(BodyModelBinder)); + options.ModelBinders.Add(new BodyModelBinder()); options.ModelBinders.Add(new HeaderModelBinder()); options.ModelBinders.Add(new TypeConverterModelBinder()); options.ModelBinders.Add(new TypeMatchModelBinder()); diff --git a/src/Microsoft.AspNet.Mvc/MvcServices.cs b/src/Microsoft.AspNet.Mvc/MvcServices.cs index 6682f2164f..23002b7c7a 100644 --- a/src/Microsoft.AspNet.Mvc/MvcServices.cs +++ b/src/Microsoft.AspNet.Mvc/MvcServices.cs @@ -10,11 +10,9 @@ using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding.Metadata; using Microsoft.AspNet.Mvc.ModelBinding.Validation; -using Microsoft.AspNet.Mvc.OptionDescriptors; using Microsoft.AspNet.Mvc.Razor; using Microsoft.AspNet.Mvc.Razor.Compilation; using Microsoft.AspNet.Mvc.Razor.Directives; -using Microsoft.AspNet.Mvc.Razor.OptionDescriptors; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Mvc.Routing; using Microsoft.AspNet.Mvc.ViewComponents; @@ -63,7 +61,12 @@ public static IServiceCollection GetDefaultServices() services.AddSingleton(); services.AddSingleton(); services.AddTransient(); - services.AddTransient(); + services.AddTransient(serviceProvider => + { + var options = serviceProvider.GetRequiredService>().Options; + var modelMetadataProvider = serviceProvider.GetRequiredService(); + return new DefaultObjectValidator(options.ValidationExcludeFilters, modelMetadataProvider); + }); services.AddTransient(); @@ -90,24 +93,14 @@ public static IServiceCollection GetDefaultServices() }); services.AddTransient(); - services.AddScoped(); - - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); services.AddInstance(new JsonOutputFormatter()); - services.AddTransient(); - services.AddTransient(); - // Razor, Views and runtime compilation // The provider is inexpensive to initialize and provides ViewEngines that may require request // specific services. services.AddScoped(); - services.AddTransient(); - // Transient since the IViewLocationExpanders returned by the instance is cached by view engines. - services.AddTransient(); + // Caches view locations that are valid for the lifetime of the application. services.AddSingleton(); services.AddSingleton(serviceProvider =>