зеркало из https://github.com/aspnet/Mvc.git
Adding an 'AddMinimalMvc()' for Mvc.Core and sample
This adds the ability to configure Mvc.Core for a project; MVC with minimal services and dependencies.
This commit is contained in:
Родитель
a665e48826
Коммит
faaba481e8
|
@ -74,6 +74,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Extens
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Extensions.Test", "test\Microsoft.AspNet.Mvc.Extensions.Test\Microsoft.AspNet.Mvc.Extensions.Test.xproj", "{5DF6EFA5-865E-450B-BF83-DE9CE88EB77C}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MvcMinimalSample.Web", "samples\MvcMinimalSample.Web\MvcMinimalSample.Web.xproj", "{F21E225B-190B-4DAA-8B0A-05986D231F56}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -419,6 +421,18 @@ Global
|
|||
{5DF6EFA5-865E-450B-BF83-DE9CE88EB77C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{5DF6EFA5-865E-450B-BF83-DE9CE88EB77C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{5DF6EFA5-865E-450B-BF83-DE9CE88EB77C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F21E225B-190B-4DAA-8B0A-05986D231F56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F21E225B-190B-4DAA-8B0A-05986D231F56}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F21E225B-190B-4DAA-8B0A-05986D231F56}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{F21E225B-190B-4DAA-8B0A-05986D231F56}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{F21E225B-190B-4DAA-8B0A-05986D231F56}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F21E225B-190B-4DAA-8B0A-05986D231F56}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F21E225B-190B-4DAA-8B0A-05986D231F56}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F21E225B-190B-4DAA-8B0A-05986D231F56}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F21E225B-190B-4DAA-8B0A-05986D231F56}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{F21E225B-190B-4DAA-8B0A-05986D231F56}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{F21E225B-190B-4DAA-8B0A-05986D231F56}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F21E225B-190B-4DAA-8B0A-05986D231F56}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -454,5 +468,6 @@ Global
|
|||
{4C2AD8AB-8AC0-46C4-80C6-C5577C7255F6} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||
{B2CA101A-87E6-4DD2-9BB2-28DA68EF1A94} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
|
||||
{5DF6EFA5-865E-450B-BF83-DE9CE88EB77C} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||
{F21E225B-190B-4DAA-8B0A-05986D231F56} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
// 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.
|
||||
|
||||
namespace MvcMinimalSample.Web
|
||||
{
|
||||
public class HomeController
|
||||
{
|
||||
public string Index()
|
||||
{
|
||||
return "Hi from MVC";
|
||||
}
|
||||
|
||||
public string GetUser(int id)
|
||||
{
|
||||
return $"User: {id}";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>f21e225b-190b-4daa-8b0a-05986d231f56</ProjectGuid>
|
||||
<RootNamespace>MvcMinimalSample.Web</RootNamespace>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<DevelopmentServerPort>4976</DevelopmentServerPort>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
|
@ -0,0 +1,21 @@
|
|||
// 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 Microsoft.AspNet.Builder;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
namespace MvcMinimalSample.Web
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddMinimalMvc();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseMvcWithDefaultRoute();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"webroot": "wwwroot",
|
||||
"version": "1.0.0-*",
|
||||
|
||||
"dependencies": {
|
||||
"Microsoft.AspNet.Mvc.Core": "6.0.0-*",
|
||||
"Microsoft.AspNet.Hosting": "1.0.0-*",
|
||||
"Microsoft.AspNet.Server.WebListener": "1.0.0-*"
|
||||
},
|
||||
|
||||
"commands": {
|
||||
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000"
|
||||
},
|
||||
|
||||
"frameworks": {
|
||||
"dnx451": { },
|
||||
"dnxcore50": { }
|
||||
},
|
||||
|
||||
"publishExclude": [
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"**.xproj",
|
||||
"**.user",
|
||||
"**.vspscc"
|
||||
],
|
||||
"exclude": [
|
||||
"wwwroot",
|
||||
"node_modules",
|
||||
"bower_components"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Minimal MVC Sample</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello, World!</h1>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,67 @@
|
|||
// 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 Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding.Metadata;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets up default options for <see cref="MvcOptions"/>.
|
||||
/// </summary>
|
||||
public class CoreMvcOptionsSetup : ConfigureOptions<MvcOptions>
|
||||
{
|
||||
public CoreMvcOptionsSetup()
|
||||
: base(ConfigureMvc)
|
||||
{
|
||||
Order = DefaultOrder.DefaultFrameworkSortOrder;
|
||||
}
|
||||
|
||||
public static void ConfigureMvc(MvcOptions options)
|
||||
{
|
||||
// Set up ModelBinding
|
||||
options.ModelBinders.Add(new BinderTypeBasedModelBinder());
|
||||
options.ModelBinders.Add(new ServicesModelBinder());
|
||||
options.ModelBinders.Add(new BodyModelBinder());
|
||||
options.ModelBinders.Add(new HeaderModelBinder());
|
||||
options.ModelBinders.Add(new TypeConverterModelBinder());
|
||||
options.ModelBinders.Add(new TypeMatchModelBinder());
|
||||
options.ModelBinders.Add(new CancellationTokenModelBinder());
|
||||
options.ModelBinders.Add(new ByteArrayModelBinder());
|
||||
options.ModelBinders.Add(new FormFileModelBinder());
|
||||
options.ModelBinders.Add(new FormCollectionModelBinder());
|
||||
options.ModelBinders.Add(new GenericModelBinder());
|
||||
options.ModelBinders.Add(new MutableObjectModelBinder());
|
||||
options.ModelBinders.Add(new ComplexModelDtoModelBinder());
|
||||
|
||||
// Set up default output formatters.
|
||||
options.OutputFormatters.Add(new HttpNoContentOutputFormatter());
|
||||
options.OutputFormatters.Add(new StringOutputFormatter());
|
||||
options.OutputFormatters.Add(new StreamOutputFormatter());
|
||||
|
||||
// Set up ValueProviders
|
||||
options.ValueProviderFactories.Add(new RouteValueValueProviderFactory());
|
||||
options.ValueProviderFactories.Add(new QueryStringValueProviderFactory());
|
||||
options.ValueProviderFactories.Add(new FormValueProviderFactory());
|
||||
|
||||
// Set up metadata providers
|
||||
options.ModelMetadataDetailsProviders.Add(new DefaultBindingMetadataProvider());
|
||||
options.ModelMetadataDetailsProviders.Add(new DefaultValidationMetadataProvider());
|
||||
|
||||
// Set up validators
|
||||
options.ModelValidatorProviders.Add(new DefaultModelValidatorProvider());
|
||||
|
||||
// Add types to be excluded from Validation
|
||||
options.ValidationExcludeFilters.Add(new SimpleTypesExcludeFilter());
|
||||
options.ValidationExcludeFilters.Add(typeof(Type));
|
||||
|
||||
// Any 'known' types that we bind should be marked as excluded from validation.
|
||||
options.ValidationExcludeFilters.Add(typeof(System.Threading.CancellationToken));
|
||||
options.ValidationExcludeFilters.Add(typeof(Http.IFormFile));
|
||||
options.ValidationExcludeFilters.Add(typeof(Http.IFormCollection));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
// 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.Diagnostics;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.ActionConstraints;
|
||||
using Microsoft.AspNet.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNet.Mvc.Core;
|
||||
using Microsoft.AspNet.Mvc.Filters;
|
||||
using Microsoft.AspNet.Mvc.Internal;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding.Metadata;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.AspNet.Mvc.Routing;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.Framework.Internal;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
||||
namespace Microsoft.Framework.DependencyInjection
|
||||
{
|
||||
public static class MvcCoreServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddMinimalMvc([NotNull] this IServiceCollection services)
|
||||
{
|
||||
ConfigureDefaultServices(services);
|
||||
|
||||
AddMvcCoreServices(services);
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures a set of <see cref="MvcOptions"/> for the application.
|
||||
/// </summary>
|
||||
/// <param name="services">The services available in the application.</param>
|
||||
/// <param name="setupAction">The <see cref="MvcOptions"/> which need to be configured.</param>
|
||||
public static void ConfigureMvc(
|
||||
[NotNull] this IServiceCollection services,
|
||||
[NotNull] Action<MvcOptions> setupAction)
|
||||
{
|
||||
services.Configure(setupAction);
|
||||
}
|
||||
|
||||
// To enable unit testing
|
||||
internal static void AddMvcCoreServices(IServiceCollection services)
|
||||
{
|
||||
// Options
|
||||
//
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IConfigureOptions<MvcOptions>, CoreMvcOptionsSetup>());
|
||||
|
||||
// Action Discovery
|
||||
//
|
||||
// These are consumed only when creating action descriptors, then they can be de-allocated
|
||||
services.TryAdd(ServiceDescriptor.Transient<IAssemblyProvider, DefaultAssemblyProvider>());
|
||||
services.TryAdd(ServiceDescriptor.Transient<IControllerTypeProvider, DefaultControllerTypeProvider>()); ;
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IApplicationModelProvider, DefaultApplicationModelProvider>());
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IActionDescriptorProvider, ControllerActionDescriptorProvider>());
|
||||
services.TryAdd(ServiceDescriptor
|
||||
.Singleton<IActionDescriptorsCollectionProvider, DefaultActionDescriptorsCollectionProvider>());
|
||||
|
||||
// Action Selection
|
||||
//
|
||||
services.TryAdd(ServiceDescriptor.Singleton<IActionSelector, DefaultActionSelector>());
|
||||
// Performs caching
|
||||
services.TryAdd(ServiceDescriptor
|
||||
.Singleton<IActionSelectorDecisionTreeProvider, ActionSelectorDecisionTreeProvider>());
|
||||
// This provider needs access to the per-request services, but might be used many times for a given
|
||||
// request.
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IActionConstraintProvider, DefaultActionConstraintProvider>());
|
||||
|
||||
// Action Invoker
|
||||
//
|
||||
// This has a cache, so it needs to be a singleton
|
||||
services.TryAdd(ServiceDescriptor.Singleton<IControllerFactory, DefaultControllerFactory>());
|
||||
services.TryAdd(ServiceDescriptor.Transient<IControllerActivator, DefaultControllerActivator>());
|
||||
// This accesses per-request services
|
||||
services.TryAdd(ServiceDescriptor.Transient<IActionInvokerFactory, ActionInvokerFactory>());
|
||||
services.TryAdd(ServiceDescriptor
|
||||
.Transient<IControllerActionArgumentBinder, DefaultControllerActionArgumentBinder>());
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IActionInvokerProvider, ControllerActionInvokerProvider>());
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IFilterProvider, DefaultFilterProvider>());
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IControllerPropertyActivator, DefaultControllerPropertyActivator>());
|
||||
|
||||
// ModelBinding, Validation and Formatting
|
||||
//
|
||||
// The DefaultModelMetadataProvider does significant caching and should be a singleton.
|
||||
services.TryAdd(ServiceDescriptor.Singleton<IModelMetadataProvider, DefaultModelMetadataProvider>());
|
||||
services.TryAdd(ServiceDescriptor.Transient<ICompositeMetadataDetailsProvider>(serviceProvider =>
|
||||
{
|
||||
var options = serviceProvider.GetRequiredService<IOptions<MvcOptions>>().Options;
|
||||
return new DefaultCompositeMetadataDetailsProvider(options.ModelMetadataDetailsProviders);
|
||||
}));
|
||||
services.TryAdd(ServiceDescriptor.Transient<IObjectModelValidator>(serviceProvider =>
|
||||
{
|
||||
var options = serviceProvider.GetRequiredService<IOptions<MvcOptions>>().Options;
|
||||
var modelMetadataProvider = serviceProvider.GetRequiredService<IModelMetadataProvider>();
|
||||
return new DefaultObjectValidator(options.ValidationExcludeFilters, modelMetadataProvider);
|
||||
}));
|
||||
|
||||
// Temp Data
|
||||
//
|
||||
services.TryAdd(ServiceDescriptor.Scoped<ITempDataDictionary, TempDataDictionary>());
|
||||
// This does caching so it should stay singleton
|
||||
services.TryAdd(ServiceDescriptor.Singleton<ITempDataProvider, SessionStateTempDataProvider>());
|
||||
|
||||
// Random Infrastructure
|
||||
//
|
||||
services.TryAdd(ServiceDescriptor.Transient<MvcMarkerService, MvcMarkerService>());
|
||||
services.TryAdd((ServiceDescriptor.Singleton<ITypeActivatorCache, DefaultTypeActivatorCache>()));
|
||||
services.TryAdd(ServiceDescriptor.Scoped(typeof(IScopedInstance<>), typeof(ScopedInstance<>)));
|
||||
services.TryAdd(ServiceDescriptor.Scoped<IUrlHelper, UrlHelper>());
|
||||
}
|
||||
|
||||
// Adds a service if the service type and implementation type hasn't been added yet. This is needed for
|
||||
// services like IConfigureOptions<MvcOptions> or IApplicationModelProvider where you need the ability
|
||||
// to register multiple implementation types for the same service type.
|
||||
private static bool TryAddMultiRegistrationService(IServiceCollection services, ServiceDescriptor descriptor)
|
||||
{
|
||||
// This can't work when registering a factory or instance, you have to register a type.
|
||||
// Additionally, if any existing registrations use a factory or instance, we can't check those, but we don't
|
||||
// assert that because it might be added by user-code.
|
||||
Debug.Assert(descriptor.ImplementationType != null);
|
||||
|
||||
if (services.Any(d =>
|
||||
d.ServiceType == descriptor.ServiceType &&
|
||||
d.ImplementationType == descriptor.ImplementationType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
services.Add(descriptor);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void ConfigureDefaultServices(IServiceCollection services)
|
||||
{
|
||||
services.AddOptions();
|
||||
services.AddRouting();
|
||||
services.AddCors();
|
||||
services.AddNotifier();
|
||||
services.Configure<RouteOptions>(
|
||||
routeOptions => routeOptions.ConstraintMap.Add("exists", typeof(KnownRouteValueConstraint)));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,10 @@
|
|||
// 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.Xml.Linq;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding.Metadata;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
|
@ -20,57 +17,18 @@ namespace Microsoft.AspNet.Mvc
|
|||
public MvcOptionsSetup()
|
||||
: base(ConfigureMvc)
|
||||
{
|
||||
Order = DefaultOrder.DefaultFrameworkSortOrder;
|
||||
Order = DefaultOrder.DefaultFrameworkSortOrder + 1;
|
||||
}
|
||||
|
||||
public static void ConfigureMvc(MvcOptions options)
|
||||
{
|
||||
// Set up ModelBinding
|
||||
options.ModelBinders.Add(new BinderTypeBasedModelBinder());
|
||||
options.ModelBinders.Add(new ServicesModelBinder());
|
||||
options.ModelBinders.Add(new BodyModelBinder());
|
||||
options.ModelBinders.Add(new HeaderModelBinder());
|
||||
options.ModelBinders.Add(new TypeConverterModelBinder());
|
||||
options.ModelBinders.Add(new TypeMatchModelBinder());
|
||||
options.ModelBinders.Add(new CancellationTokenModelBinder());
|
||||
options.ModelBinders.Add(new ByteArrayModelBinder());
|
||||
options.ModelBinders.Add(new FormFileModelBinder());
|
||||
options.ModelBinders.Add(new FormCollectionModelBinder());
|
||||
options.ModelBinders.Add(new GenericModelBinder());
|
||||
options.ModelBinders.Add(new MutableObjectModelBinder());
|
||||
options.ModelBinders.Add(new ComplexModelDtoModelBinder());
|
||||
|
||||
// Set up default output formatters.
|
||||
options.OutputFormatters.Add(new HttpNoContentOutputFormatter());
|
||||
options.OutputFormatters.Add(new StringOutputFormatter());
|
||||
options.OutputFormatters.Add(new StreamOutputFormatter());
|
||||
|
||||
// Set up ValueProviders
|
||||
options.ValueProviderFactories.Add(new RouteValueValueProviderFactory());
|
||||
options.ValueProviderFactories.Add(new QueryStringValueProviderFactory());
|
||||
options.ValueProviderFactories.Add(new FormValueProviderFactory());
|
||||
|
||||
// Set up metadata providers
|
||||
options.ModelMetadataDetailsProviders.Add(new DefaultBindingMetadataProvider());
|
||||
options.ModelMetadataDetailsProviders.Add(new DefaultValidationMetadataProvider());
|
||||
options.ModelMetadataDetailsProviders.Add(new DataAnnotationsMetadataProvider());
|
||||
options.ModelMetadataDetailsProviders.Add(new DataMemberRequiredBindingMetadataProvider());
|
||||
|
||||
// Set up validators
|
||||
options.ModelValidatorProviders.Add(new DefaultModelValidatorProvider());
|
||||
options.ModelValidatorProviders.Add(new DataAnnotationsModelValidatorProvider());
|
||||
|
||||
// Add types to be excluded from Validation
|
||||
options.ValidationExcludeFilters.Add(new SimpleTypesExcludeFilter());
|
||||
options.ValidationExcludeFilters.Add(typeof(XObject));
|
||||
options.ValidationExcludeFilters.Add(typeof(Type));
|
||||
options.ValidationExcludeFilters.Add(typeof(JToken));
|
||||
|
||||
// Any 'known' types that we bind should be marked as excluded from validation.
|
||||
options.ValidationExcludeFilters.Add(typeof(System.Threading.CancellationToken));
|
||||
options.ValidationExcludeFilters.Add(typeof(Http.IFormFile));
|
||||
options.ValidationExcludeFilters.Add(typeof(Http.IFormCollection));
|
||||
|
||||
options.ValidationExcludeFilters.Add(typeFullName: "System.Xml.XmlNode");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,22 +7,13 @@ using System.Diagnostics;
|
|||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.ActionConstraints;
|
||||
using Microsoft.AspNet.Mvc.ApiExplorer;
|
||||
using Microsoft.AspNet.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNet.Mvc.Core;
|
||||
using Microsoft.AspNet.Mvc.Filters;
|
||||
using Microsoft.AspNet.Mvc.Internal;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding.Metadata;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.AspNet.Mvc.Razor;
|
||||
using Microsoft.AspNet.Mvc.Razor.Compilation;
|
||||
using Microsoft.AspNet.Mvc.Razor.Directives;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
using Microsoft.AspNet.Mvc.Routing;
|
||||
using Microsoft.AspNet.Mvc.ViewComponents;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.Framework.Caching.Memory;
|
||||
using Microsoft.Framework.Internal;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
@ -33,6 +24,8 @@ namespace Microsoft.Framework.DependencyInjection
|
|||
{
|
||||
public static IServiceCollection AddMvc([NotNull] this IServiceCollection services)
|
||||
{
|
||||
services.AddMinimalMvc();
|
||||
|
||||
ConfigureDefaultServices(services);
|
||||
|
||||
AddMvcServices(services);
|
||||
|
@ -52,18 +45,6 @@ namespace Microsoft.Framework.DependencyInjection
|
|||
services.Configure(setupAction);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures a set of <see cref="MvcOptions"/> for the application.
|
||||
/// </summary>
|
||||
/// <param name="services">The services available in the application.</param>
|
||||
/// <param name="setupAction">The <see cref="MvcOptions"/> which need to be configured.</param>
|
||||
public static void ConfigureMvc(
|
||||
[NotNull] this IServiceCollection services,
|
||||
[NotNull] Action<MvcOptions> setupAction)
|
||||
{
|
||||
services.Configure(setupAction);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures a set of <see cref="MvcFormatterMappingOptions"/> for the application.
|
||||
/// </summary>
|
||||
|
@ -182,86 +163,25 @@ namespace Microsoft.Framework.DependencyInjection
|
|||
ServiceDescriptor
|
||||
.Transient<IConfigureOptions<RazorViewEngineOptions>, RazorViewEngineOptionsSetup>());
|
||||
|
||||
services.TryAdd(ServiceDescriptor.Transient<MvcMarkerService, MvcMarkerService>());
|
||||
services.TryAdd((ServiceDescriptor.Singleton<ITypeActivatorCache, DefaultTypeActivatorCache>()));
|
||||
services.TryAdd(ServiceDescriptor.Scoped(typeof(IScopedInstance<>), typeof(ScopedInstance<>)));
|
||||
|
||||
// Core action discovery, filters and action execution.
|
||||
|
||||
// This are consumed only when creating action descriptors, then they can be de-allocated
|
||||
services.TryAdd(ServiceDescriptor.Transient<IAssemblyProvider, DefaultAssemblyProvider>());
|
||||
services.TryAdd(ServiceDescriptor.Transient<IControllerTypeProvider, DefaultControllerTypeProvider>()); ;
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IApplicationModelProvider, DefaultApplicationModelProvider>());
|
||||
// Cors
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IApplicationModelProvider, CorsApplicationModelProvider>());
|
||||
services.TryAdd(ServiceDescriptor.Transient<CorsAuthorizationFilter, CorsAuthorizationFilter>());
|
||||
|
||||
// Auth
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IApplicationModelProvider, AuthorizationApplicationModelProvider>());
|
||||
|
||||
// This has a cache, so it needs to be a singleton
|
||||
services.TryAdd(ServiceDescriptor.Singleton<IControllerFactory, DefaultControllerFactory>());
|
||||
|
||||
services.TryAdd(ServiceDescriptor.Transient<IControllerActivator, DefaultControllerActivator>());
|
||||
|
||||
// This accesses per-request services
|
||||
services.TryAdd(ServiceDescriptor.Transient<IActionInvokerFactory, ActionInvokerFactory>());
|
||||
|
||||
// This provider needs access to the per-request services, but might be used many times for a given
|
||||
// request.
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IActionConstraintProvider, DefaultActionConstraintProvider>());
|
||||
|
||||
services.TryAdd(ServiceDescriptor
|
||||
.Singleton<IActionSelectorDecisionTreeProvider, ActionSelectorDecisionTreeProvider>());
|
||||
services.TryAdd(ServiceDescriptor.Singleton<IActionSelector, DefaultActionSelector>());
|
||||
services.TryAdd(ServiceDescriptor
|
||||
.Transient<IControllerActionArgumentBinder, DefaultControllerActionArgumentBinder>());
|
||||
services.TryAdd(ServiceDescriptor.Transient<IObjectModelValidator>(serviceProvider =>
|
||||
{
|
||||
var options = serviceProvider.GetRequiredService<IOptions<MvcOptions>>().Options;
|
||||
var modelMetadataProvider = serviceProvider.GetRequiredService<IModelMetadataProvider>();
|
||||
return new DefaultObjectValidator(options.ValidationExcludeFilters, modelMetadataProvider);
|
||||
}));
|
||||
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IActionDescriptorProvider, ControllerActionDescriptorProvider>());
|
||||
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IActionInvokerProvider, ControllerActionInvokerProvider>());
|
||||
|
||||
services.TryAdd(ServiceDescriptor
|
||||
.Singleton<IActionDescriptorsCollectionProvider, DefaultActionDescriptorsCollectionProvider>());
|
||||
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IFilterProvider, DefaultFilterProvider>());
|
||||
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IControllerPropertyActivator, DefaultControllerPropertyActivator>());
|
||||
// Support for activating ViewDataDictionary
|
||||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor
|
||||
.Transient<IControllerPropertyActivator, ViewDataDictionaryControllerPropertyActivator>());
|
||||
|
||||
// Formatter Mappings
|
||||
services.TryAdd(ServiceDescriptor.Transient<FormatFilter, FormatFilter>());
|
||||
services.TryAdd(ServiceDescriptor.Transient<CorsAuthorizationFilter, CorsAuthorizationFilter>());
|
||||
|
||||
// Dataflow - ModelBinding, Validation and Formatting
|
||||
//
|
||||
// The DefaultModelMetadataProvider does significant caching and should be a singleton.
|
||||
services.TryAdd(ServiceDescriptor.Singleton<IModelMetadataProvider, DefaultModelMetadataProvider>());
|
||||
services.TryAdd(ServiceDescriptor.Transient<ICompositeMetadataDetailsProvider>(serviceProvider =>
|
||||
{
|
||||
var options = serviceProvider.GetRequiredService<IOptions<MvcOptions>>().Options;
|
||||
return new DefaultCompositeMetadataDetailsProvider(options.ModelMetadataDetailsProviders);
|
||||
}));
|
||||
|
||||
// JsonOutputFormatter should use the SerializerSettings on MvcOptions
|
||||
services.TryAdd(ServiceDescriptor.Singleton<JsonOutputFormatter>(serviceProvider =>
|
||||
|
@ -311,7 +231,6 @@ namespace Microsoft.Framework.DependencyInjection
|
|||
services.TryAdd(ServiceDescriptor.Transient<IHtmlHelper, HtmlHelper>());
|
||||
services.TryAdd(ServiceDescriptor.Transient(typeof(IHtmlHelper<>), typeof(HtmlHelper<>)));
|
||||
services.TryAdd(ServiceDescriptor.Transient<IJsonHelper, JsonHelper>());
|
||||
services.TryAdd(ServiceDescriptor.Scoped<IUrlHelper, UrlHelper>());
|
||||
|
||||
// Only want one ITagHelperActivator so it can cache Type activation information. Types won't conflict.
|
||||
services.TryAdd(ServiceDescriptor.Singleton<ITagHelperActivator, DefaultTagHelperActivator>());
|
||||
|
@ -348,11 +267,6 @@ namespace Microsoft.Framework.DependencyInjection
|
|||
TryAddMultiRegistrationService(
|
||||
services,
|
||||
ServiceDescriptor.Transient<IApiDescriptionProvider, DefaultApiDescriptionProvider>());
|
||||
|
||||
// Temp Data
|
||||
services.TryAdd(ServiceDescriptor.Scoped<ITempDataDictionary, TempDataDictionary>());
|
||||
// This does caching so it should stay singleton
|
||||
services.TryAdd(ServiceDescriptor.Singleton<ITempDataProvider, SessionStateTempDataProvider>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -406,15 +320,10 @@ namespace Microsoft.Framework.DependencyInjection
|
|||
|
||||
private static void ConfigureDefaultServices(IServiceCollection services)
|
||||
{
|
||||
services.AddOptions();
|
||||
services.AddDataProtection();
|
||||
services.AddRouting();
|
||||
services.AddCors();
|
||||
services.AddAuthorization();
|
||||
services.AddWebEncoders();
|
||||
services.AddNotifier();
|
||||
services.Configure<RouteOptions>(
|
||||
routeOptions => routeOptions.ConstraintMap.Add("exists", typeof(KnownRouteValueConstraint)));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
// 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.Linq;
|
||||
using Microsoft.AspNet.Mvc.ActionConstraints;
|
||||
using Microsoft.AspNet.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNet.Mvc.Core;
|
||||
using Microsoft.AspNet.Mvc.Filters;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public class MvcCoreServiceCollectionExtensionsTest
|
||||
{
|
||||
// Some MVC services can be registered multiple times, for example, 'IConfigureOptions<MvcOptions>' can
|
||||
// be registered by calling 'ConfigureMvc(...)' before the call to 'AddMvc()' in which case the options
|
||||
// configuration is run in the order they were registered.
|
||||
//
|
||||
// For these kind of multi registration service types, we want to make sure that MVC will still add its
|
||||
// services if the implementation type is different.
|
||||
[Fact]
|
||||
public void MultiRegistrationServiceTypes_AreRegistered_MultipleTimes()
|
||||
{
|
||||
// Arrange
|
||||
var services = new ServiceCollection();
|
||||
|
||||
// Register a mock implementation of each service, AddMvcServices should add another implemenetation.
|
||||
foreach (var serviceType in MutliRegistrationServiceTypes)
|
||||
{
|
||||
var mockType = typeof(Mock<>).MakeGenericType(serviceType.Key);
|
||||
services.Add(ServiceDescriptor.Transient(serviceType.Key, mockType));
|
||||
}
|
||||
|
||||
// Act
|
||||
MvcCoreServiceCollectionExtensions.AddMvcCoreServices(services);
|
||||
|
||||
// Assert
|
||||
foreach (var serviceType in MutliRegistrationServiceTypes)
|
||||
{
|
||||
AssertServiceCountEquals(services, serviceType.Key, serviceType.Value.Length + 1);
|
||||
|
||||
foreach (var implementationType in serviceType.Value)
|
||||
{
|
||||
AssertContainsSingle(services, serviceType.Key, implementationType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SingleRegistrationServiceTypes_AreNotRegistered_MultipleTimes()
|
||||
{
|
||||
// Arrange
|
||||
var services = new ServiceCollection();
|
||||
|
||||
// Register a mock implementation of each service, AddMvcServices should not replace it.
|
||||
foreach (var serviceType in SingleRegistrationServiceTypes)
|
||||
{
|
||||
var mockType = typeof(Mock<>).MakeGenericType(serviceType);
|
||||
services.Add(ServiceDescriptor.Transient(serviceType, mockType));
|
||||
}
|
||||
|
||||
// Act
|
||||
MvcCoreServiceCollectionExtensions.AddMvcCoreServices(services);
|
||||
|
||||
// Assert
|
||||
foreach (var singleRegistrationType in SingleRegistrationServiceTypes)
|
||||
{
|
||||
AssertServiceCountEquals(services, singleRegistrationType, 1);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddMvcServicesTwice_DoesNotAddDuplicates()
|
||||
{
|
||||
// Arrange
|
||||
var services = new ServiceCollection();
|
||||
|
||||
// Act
|
||||
MvcCoreServiceCollectionExtensions.AddMvcCoreServices(services);
|
||||
MvcCoreServiceCollectionExtensions.AddMvcCoreServices(services);
|
||||
|
||||
// Assert
|
||||
var singleRegistrationServiceTypes = SingleRegistrationServiceTypes;
|
||||
foreach (var service in services)
|
||||
{
|
||||
if (singleRegistrationServiceTypes.Contains(service.ServiceType))
|
||||
{
|
||||
// 'single-registration' services should only have one implementation registered.
|
||||
AssertServiceCountEquals(services, service.ServiceType, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 'multi-registration' services should only have one *instance* of each implementation registered.
|
||||
AssertContainsSingle(services, service.ServiceType, service.ImplementationType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<Type> SingleRegistrationServiceTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
MvcCoreServiceCollectionExtensions.AddMvcCoreServices(services);
|
||||
|
||||
var multiRegistrationServiceTypes = MutliRegistrationServiceTypes;
|
||||
return services
|
||||
.Where(sd => !multiRegistrationServiceTypes.Keys.Contains(sd.ServiceType))
|
||||
.Select(sd => sd.ServiceType);
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<Type, Type[]> MutliRegistrationServiceTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Dictionary<Type, Type[]>()
|
||||
{
|
||||
{
|
||||
typeof(IConfigureOptions<MvcOptions>),
|
||||
new Type[]
|
||||
{
|
||||
typeof(CoreMvcOptionsSetup),
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(IActionConstraintProvider),
|
||||
new Type[]
|
||||
{
|
||||
typeof(DefaultActionConstraintProvider),
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(IActionDescriptorProvider),
|
||||
new Type[]
|
||||
{
|
||||
typeof(ControllerActionDescriptorProvider),
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(IActionInvokerProvider),
|
||||
new Type[]
|
||||
{
|
||||
typeof(ControllerActionInvokerProvider),
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(IFilterProvider),
|
||||
new Type[]
|
||||
{
|
||||
typeof(DefaultFilterProvider),
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(IControllerPropertyActivator),
|
||||
new Type[]
|
||||
{
|
||||
typeof(DefaultControllerPropertyActivator),
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(IApplicationModelProvider),
|
||||
new Type[]
|
||||
{
|
||||
typeof(DefaultApplicationModelProvider),
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void AssertServiceCountEquals(
|
||||
IServiceCollection services,
|
||||
Type serviceType,
|
||||
int expectedServiceRegistrationCount)
|
||||
{
|
||||
var serviceDescriptors = services.Where(serviceDescriptor => serviceDescriptor.ServiceType == serviceType);
|
||||
var actual = serviceDescriptors.Count();
|
||||
|
||||
Assert.True(
|
||||
(expectedServiceRegistrationCount == actual),
|
||||
$"Expected service type '{serviceType}' to be registered {expectedServiceRegistrationCount}" +
|
||||
$" time(s) but was actually registered {actual} time(s).");
|
||||
}
|
||||
|
||||
private void AssertContainsSingle(
|
||||
IServiceCollection services,
|
||||
Type serviceType,
|
||||
Type implementationType)
|
||||
{
|
||||
var matches = services
|
||||
.Where(sd =>
|
||||
sd.ServiceType == serviceType &&
|
||||
sd.ImplementationType == implementationType)
|
||||
.ToArray();
|
||||
|
||||
if (matches.Length == 0)
|
||||
{
|
||||
Assert.True(
|
||||
false,
|
||||
$"Could not find an instance of {implementationType} registered as {serviceType}");
|
||||
}
|
||||
else if (matches.Length > 1)
|
||||
{
|
||||
Assert.True(
|
||||
false,
|
||||
$"Found multiple instances of {implementationType} registered as {serviceType}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
|
|||
public TestMvcOptions()
|
||||
{
|
||||
Options = new MvcOptions();
|
||||
CoreMvcOptionsSetup.ConfigureMvc(Options);
|
||||
MvcOptionsSetup.ConfigureMvc(Options);
|
||||
JsonMvcOptionsSetup.ConfigureMvc(Options, SerializerSettingsProvider.CreateSerializerSettings());
|
||||
}
|
||||
|
|
|
@ -35,10 +35,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Arrange
|
||||
var mvcOptions = new MvcOptions();
|
||||
var setup = new MvcOptionsSetup();
|
||||
var setup1 = new CoreMvcOptionsSetup();
|
||||
var setup2 = new MvcOptionsSetup();
|
||||
|
||||
// Act
|
||||
setup.Configure(mvcOptions);
|
||||
setup1.Configure(mvcOptions);
|
||||
setup2.Configure(mvcOptions);
|
||||
|
||||
// Assert
|
||||
var i = 0;
|
||||
|
@ -63,10 +65,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Arrange
|
||||
var mvcOptions = new MvcOptions();
|
||||
var setup = new MvcOptionsSetup();
|
||||
var setup1 = new CoreMvcOptionsSetup();
|
||||
var setup2 = new MvcOptionsSetup();
|
||||
|
||||
// Act
|
||||
setup.Configure(mvcOptions);
|
||||
setup1.Configure(mvcOptions);
|
||||
setup2.Configure(mvcOptions);
|
||||
|
||||
// Assert
|
||||
var valueProviders = mvcOptions.ValueProviderFactories;
|
||||
|
@ -81,13 +85,15 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Arrange
|
||||
var mvcOptions = new MvcOptions();
|
||||
var setup1 = new MvcOptionsSetup();
|
||||
var setup2 = new JsonMvcOptionsSetup(new OptionsManager<MvcJsonOptions>(
|
||||
var setup1 = new CoreMvcOptionsSetup();
|
||||
var setup2 = new MvcOptionsSetup();
|
||||
var setup3 = new JsonMvcOptionsSetup(new OptionsManager<MvcJsonOptions>(
|
||||
Enumerable.Empty<IConfigureOptions<MvcJsonOptions>>()));
|
||||
|
||||
// Act
|
||||
setup1.Configure(mvcOptions);
|
||||
setup2.Configure(mvcOptions);
|
||||
setup3.Configure(mvcOptions);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(4, mvcOptions.OutputFormatters.Count);
|
||||
|
@ -102,13 +108,15 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Arrange
|
||||
var mvcOptions = new MvcOptions();
|
||||
var setup1 = new MvcOptionsSetup();
|
||||
var setup2 = new JsonMvcOptionsSetup(new OptionsManager<MvcJsonOptions>(
|
||||
var setup1 = new CoreMvcOptionsSetup();
|
||||
var setup2 = new MvcOptionsSetup();
|
||||
var setup3 = new JsonMvcOptionsSetup(new OptionsManager<MvcJsonOptions>(
|
||||
Enumerable.Empty<IConfigureOptions<MvcJsonOptions>>()));
|
||||
|
||||
// Act
|
||||
setup1.Configure(mvcOptions);
|
||||
setup2.Configure(mvcOptions);
|
||||
setup3.Configure(mvcOptions);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(2, mvcOptions.InputFormatters.Count);
|
||||
|
@ -121,10 +129,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Arrange
|
||||
var mvcOptions = new MvcOptions();
|
||||
var setup = new MvcOptionsSetup();
|
||||
var setup1 = new CoreMvcOptionsSetup();
|
||||
var setup2 = new MvcOptionsSetup();
|
||||
|
||||
// Act
|
||||
setup.Configure(mvcOptions);
|
||||
setup1.Configure(mvcOptions);
|
||||
setup2.Configure(mvcOptions);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(2, mvcOptions.ModelValidatorProviders.Count);
|
||||
|
@ -153,7 +163,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Arrange
|
||||
var mvcOptions = new MvcOptions();
|
||||
var setup = new MvcOptionsSetup();
|
||||
var setup = new CoreMvcOptionsSetup();
|
||||
|
||||
// Act
|
||||
setup.Configure(mvcOptions);
|
||||
|
@ -167,10 +177,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Arrange
|
||||
var mvcOptions = new MvcOptions();
|
||||
var setup = new MvcOptionsSetup();
|
||||
var setup1 = new CoreMvcOptionsSetup();
|
||||
var setup2 = new MvcOptionsSetup();
|
||||
|
||||
// Act
|
||||
setup.Configure(mvcOptions);
|
||||
setup1.Configure(mvcOptions);
|
||||
setup2.Configure(mvcOptions);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(8, mvcOptions.ValidationExcludeFilters.Count);
|
||||
|
@ -178,21 +190,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
// Verify if the delegates registered by default exclude the given types.
|
||||
Assert.IsType(typeof(SimpleTypesExcludeFilter), mvcOptions.ValidationExcludeFilters[i++]);
|
||||
Assert.IsType(typeof(DefaultTypeBasedExcludeFilter), mvcOptions.ValidationExcludeFilters[i]);
|
||||
var xObjectFilter
|
||||
= Assert.IsType<DefaultTypeBasedExcludeFilter>(mvcOptions.ValidationExcludeFilters[i++]);
|
||||
Assert.Equal(xObjectFilter.ExcludedType, typeof(XObject));
|
||||
|
||||
Assert.IsType(typeof(DefaultTypeBasedExcludeFilter), mvcOptions.ValidationExcludeFilters[i]);
|
||||
var typeFilter
|
||||
= Assert.IsType<DefaultTypeBasedExcludeFilter>(mvcOptions.ValidationExcludeFilters[i++]);
|
||||
Assert.Equal(typeFilter.ExcludedType, typeof(Type));
|
||||
|
||||
Assert.IsType(typeof(DefaultTypeBasedExcludeFilter), mvcOptions.ValidationExcludeFilters[i]);
|
||||
var jTokenFilter
|
||||
= Assert.IsType<DefaultTypeBasedExcludeFilter>(mvcOptions.ValidationExcludeFilters[i++]);
|
||||
Assert.Equal(jTokenFilter.ExcludedType, typeof(JToken));
|
||||
|
||||
Assert.IsType(typeof(DefaultTypeBasedExcludeFilter), mvcOptions.ValidationExcludeFilters[i]);
|
||||
var cancellationTokenFilter
|
||||
= Assert.IsType<DefaultTypeBasedExcludeFilter>(mvcOptions.ValidationExcludeFilters[i++]);
|
||||
|
@ -210,6 +213,16 @@ namespace Microsoft.AspNet.Mvc
|
|||
= Assert.IsType<DefaultTypeBasedExcludeFilter>(mvcOptions.ValidationExcludeFilters[i++]);
|
||||
Assert.Equal(formCollectionFilter.ExcludedType, typeof(Http.IFormCollection));
|
||||
|
||||
Assert.IsType(typeof(DefaultTypeBasedExcludeFilter), mvcOptions.ValidationExcludeFilters[i]);
|
||||
var xObjectFilter
|
||||
= Assert.IsType<DefaultTypeBasedExcludeFilter>(mvcOptions.ValidationExcludeFilters[i++]);
|
||||
Assert.Equal(xObjectFilter.ExcludedType, typeof(XObject));
|
||||
|
||||
Assert.IsType(typeof(DefaultTypeBasedExcludeFilter), mvcOptions.ValidationExcludeFilters[i]);
|
||||
var jTokenFilter
|
||||
= Assert.IsType<DefaultTypeBasedExcludeFilter>(mvcOptions.ValidationExcludeFilters[i++]);
|
||||
Assert.Equal(jTokenFilter.ExcludedType, typeof(JToken));
|
||||
|
||||
Assert.IsType(typeof(DefaultTypeNameBasedExcludeFilter), mvcOptions.ValidationExcludeFilters[i]);
|
||||
var xmlNodeFilter =
|
||||
Assert.IsType<DefaultTypeNameBasedExcludeFilter>(mvcOptions.ValidationExcludeFilters[i++]);
|
||||
|
|
|
@ -219,34 +219,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
typeof(RazorViewEngineOptionsSetup),
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(IActionConstraintProvider),
|
||||
new Type[]
|
||||
{
|
||||
typeof(DefaultActionConstraintProvider),
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(IActionDescriptorProvider),
|
||||
new Type[]
|
||||
{
|
||||
typeof(ControllerActionDescriptorProvider),
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(IActionInvokerProvider),
|
||||
new Type[]
|
||||
{
|
||||
typeof(ControllerActionInvokerProvider),
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(IFilterProvider),
|
||||
new Type[]
|
||||
{
|
||||
typeof(DefaultFilterProvider),
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(IApiDescriptionProvider),
|
||||
new Type[]
|
||||
|
@ -258,7 +230,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
typeof(IControllerPropertyActivator),
|
||||
new Type[]
|
||||
{
|
||||
typeof(DefaultControllerPropertyActivator),
|
||||
typeof(ViewDataDictionaryControllerPropertyActivator),
|
||||
}
|
||||
},
|
||||
|
@ -266,7 +237,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
typeof(IApplicationModelProvider),
|
||||
new Type[]
|
||||
{
|
||||
typeof(DefaultApplicationModelProvider),
|
||||
typeof(CorsApplicationModelProvider),
|
||||
typeof(AuthorizationApplicationModelProvider),
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче