From 9d89a8cac3cb5fb6b1aa7138814957708c2c22ca Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Thu, 13 Aug 2015 18:17:41 -0700 Subject: [PATCH] Homogenize MVC startup code patterns Use builder APIS for both AddMvc() and AddMvcCore() Change various API patterns to all use .AddXyz(...) off of one or both of these builders. --- samples/MvcSample.Web/Startup.cs | 19 ++- ...MvcApiExplorerMvcCoreBuilderExtensions.cs} | 4 +- .../DependencyInjection/IMvcCoreBuilder.cs | 10 ++ .../MvcCoreMvcBuilderExtensions.cs | 76 ++++----- .../MvcCoreMvcCoreBuilderExtensions.cs | 104 ++++++++++++ .../MvcCoreServiceCollectionExtensions.cs | 44 ++--- .../FixedSetControllerTypeProvider.cs | 1 + .../Internal/ControllersAsServices.cs | 42 +++++ .../Internal/MvcBuilder.cs | 18 +++ .../Internal/MvcCoreBuilder.cs | 18 +++ ....cs => MvcCorsMvcCoreBuilderExtensions.cs} | 12 +- ...ataAnnotationsMvcCoreBuilderExtensions.cs} | 4 +- .../MvcJsonMvcBuilderExtensions.cs | 40 ++--- .../MvcJsonMvcCoreBuilderExtensions.cs | 42 +++++ .../MvcXmlMvcCoreBuilderExtensions.cs | 52 ++++++ .../MvcOptionsExtensions.cs | 21 --- .../MvcLocalizationMvcBuilderExtensions.cs | 28 ++-- ...MvcLocalizationMvcCoreBuilderExtensions.cs | 53 ++++++ ...LocalizationServiceCollectionExtensions.cs | 56 ------- .../Internal/MvcLocalizationServices.cs | 36 +++++ .../MvcRazorMvcBuilderExtensions.cs | 152 +++++------------- .../MvcRazorMvcCoreBuilderExtensions.cs | 126 +++++++++++++++ .../Internal/RazorFileInfoCollections.cs | 34 ++++ .../RazorServiceCollectionExtensions.cs | 52 ------ .../MvcViewFeaturesMvcBuilderExtensions.cs | 103 ++---------- ...MvcViewFeaturesMvcCoreBuilderExtensions.cs | 113 +++++++++++++ ...> WebApiCompatShimMvcBuilderExtensions.cs} | 12 +- .../MvcServiceCollectionExtensions.cs | 85 ++-------- .../MvcBuilderExtensionsTest.cs | 71 ++++++++ .../HtmlGenerationTest.cs | 4 +- ...lizationServiceCollectionExtensionsTest.cs | 24 +-- .../DefaultTagHelperActivatorTest.cs | 17 +- .../RazorFileInfoCollectionsTest.cs} | 11 +- .../RazorViewEngineOptionsTest.cs | 6 +- .../MvcOptionsSetupTest.cs | 7 +- .../MvcServiceCollectionExtensionsTest.cs | 97 ----------- .../ActionConstraintsWebSite/Startup.cs | 8 +- test/WebSites/ActionResultsWebSite/Startup.cs | 10 +- test/WebSites/ApiExplorerWebSite/Startup.cs | 7 +- .../ApplicationModelWebSite/Startup.cs | 4 +- test/WebSites/BasicWebSite/Startup.cs | 8 +- .../CompositeViewEngineWebSite/Startup.cs | 5 +- .../ContentNegotiationWebSite/Startup.cs | 7 +- .../ControllersFromServicesWebSite/Startup.cs | 13 +- test/WebSites/FormatFilterWebSite/Startup.cs | 8 +- test/WebSites/FormatterWebSite/Startup.cs | 15 +- test/WebSites/LocalizationWebSite/Startup.cs | 8 +- test/WebSites/ModelBindingWebSite/Startup.cs | 22 +-- test/WebSites/RazorWebSite/Startup.cs | 35 ++-- test/WebSites/ResponseCacheWebSite/Startup.cs | 7 +- .../WebSites/ValueProvidersWebSite/Startup.cs | 14 +- .../WebApiCompatShimWebSite/Startup.cs | 3 +- 52 files changed, 983 insertions(+), 785 deletions(-) rename src/Microsoft.AspNet.Mvc.ApiExplorer/DependencyInjection/{MvcApiExplorerMvcBuilderExtensions.cs => MvcApiExplorerMvcCoreBuilderExtensions.cs} (84%) create mode 100644 src/Microsoft.AspNet.Mvc.Core/DependencyInjection/IMvcCoreBuilder.cs create mode 100644 src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreMvcCoreBuilderExtensions.cs create mode 100644 src/Microsoft.AspNet.Mvc.Core/Internal/ControllersAsServices.cs create mode 100644 src/Microsoft.AspNet.Mvc.Core/Internal/MvcBuilder.cs create mode 100644 src/Microsoft.AspNet.Mvc.Core/Internal/MvcCoreBuilder.cs rename src/Microsoft.AspNet.Mvc.Cors/DependencyInjection/{MvcCorsMvcBuilderExtensions.cs => MvcCorsMvcCoreBuilderExtensions.cs} (79%) rename src/Microsoft.AspNet.Mvc.DataAnnotations/DependencyInjection/{MvcDataAnnotationsMvcBuilderExtensions.cs => MvcDataAnnotationsMvcCoreBuilderExtensions.cs} (82%) create mode 100644 src/Microsoft.AspNet.Mvc.Formatters.Json/DependencyInjection/MvcJsonMvcCoreBuilderExtensions.cs create mode 100644 src/Microsoft.AspNet.Mvc.Formatters.Xml/DependencyInjection/MvcXmlMvcCoreBuilderExtensions.cs delete mode 100644 src/Microsoft.AspNet.Mvc.Formatters.Xml/MvcOptionsExtensions.cs create mode 100644 src/Microsoft.AspNet.Mvc.Localization/DependencyInjection/MvcLocalizationMvcCoreBuilderExtensions.cs delete mode 100644 src/Microsoft.AspNet.Mvc.Localization/DependencyInjection/MvcLocalizationServiceCollectionExtensions.cs create mode 100644 src/Microsoft.AspNet.Mvc.Localization/Internal/MvcLocalizationServices.cs create mode 100644 src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs create mode 100644 src/Microsoft.AspNet.Mvc.Razor/Internal/RazorFileInfoCollections.cs delete mode 100644 src/Microsoft.AspNet.Mvc.Razor/RazorServiceCollectionExtensions.cs create mode 100644 src/Microsoft.AspNet.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcCoreBuilderExtensions.cs rename src/Microsoft.AspNet.Mvc.WebApiCompatShim/{WebApiCompatShimServiceCollectionExtensions.cs => WebApiCompatShimMvcBuilderExtensions.cs} (67%) create mode 100644 test/Microsoft.AspNet.Mvc.Core.Test/DepenencyInjection/MvcBuilderExtensionsTest.cs rename test/Microsoft.AspNet.Mvc.Localization.Test/{DependencyInjection => Internal}/MvcLocalizationServiceCollectionExtensionsTest.cs (92%) rename test/Microsoft.AspNet.Mvc.Razor.Test/{DependencyInjection/MvcRazorMvcBuilderExtensionsTest.cs => Internal/RazorFileInfoCollectionsTest.cs} (83%) diff --git a/samples/MvcSample.Web/Startup.cs b/samples/MvcSample.Web/Startup.cs index 9b5f9dcc54..fa8fea4827 100644 --- a/samples/MvcSample.Web/Startup.cs +++ b/samples/MvcSample.Web/Startup.cs @@ -25,19 +25,18 @@ namespace MvcSample.Web services.AddCaching(); services.AddSession(); - services.AddMvc(); + services.AddMvc(options => + { + options.Filters.Add(typeof(PassThroughAttribute), order: 17); + options.Filters.Add(new FormatFilterAttribute()); + }) + .AddXmlDataContractSerializerFormatters() + .AddViewLocalization(LanguageViewLocationExpanderFormat.SubFolder); + services.AddSingleton(); services.AddSingleton(); services.AddTransient(); - - services.ConfigureMvc(options => - { - options.Filters.Add(typeof(PassThroughAttribute), order: 17); - options.AddXmlDataContractSerializerFormatter(); - options.Filters.Add(new FormatFilterAttribute()); - }); - - services.AddMvcLocalization(LanguageViewLocationExpanderFormat.SubFolder); + var applicationEnvironment = services.BuildServiceProvider().GetRequiredService(); var configurationPath = Path.Combine(applicationEnvironment.ApplicationBasePath, "config.json"); diff --git a/src/Microsoft.AspNet.Mvc.ApiExplorer/DependencyInjection/MvcApiExplorerMvcBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.ApiExplorer/DependencyInjection/MvcApiExplorerMvcCoreBuilderExtensions.cs similarity index 84% rename from src/Microsoft.AspNet.Mvc.ApiExplorer/DependencyInjection/MvcApiExplorerMvcBuilderExtensions.cs rename to src/Microsoft.AspNet.Mvc.ApiExplorer/DependencyInjection/MvcApiExplorerMvcCoreBuilderExtensions.cs index e54609726a..fc22f0cf1e 100644 --- a/src/Microsoft.AspNet.Mvc.ApiExplorer/DependencyInjection/MvcApiExplorerMvcBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.ApiExplorer/DependencyInjection/MvcApiExplorerMvcCoreBuilderExtensions.cs @@ -7,9 +7,9 @@ using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection { - public static class MvcApiExplorerMvcBuilderExtensions + public static class MvcApiExplorerMvcCoreBuilderExtensions { - public static IMvcBuilder AddApiExplorer([NotNull] this IMvcBuilder builder) + public static IMvcCoreBuilder AddApiExplorer([NotNull] this IMvcCoreBuilder builder) { AddApiExplorerServices(builder.Services); return builder; diff --git a/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/IMvcCoreBuilder.cs b/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/IMvcCoreBuilder.cs new file mode 100644 index 0000000000..978e61766c --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/IMvcCoreBuilder.cs @@ -0,0 +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. + +namespace Microsoft.Framework.DependencyInjection +{ + public interface IMvcCoreBuilder + { + IServiceCollection Services { get; } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreMvcBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreMvcBuilderExtensions.cs index 3d3c1d96aa..47aa48dc4a 100644 --- a/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreMvcBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreMvcBuilderExtensions.cs @@ -2,66 +2,56 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Authorization; +using System.Collections.Generic; +using System.Reflection; using Microsoft.AspNet.Mvc; -using Microsoft.AspNet.Mvc.ApplicationModels; -using Microsoft.Framework.DependencyInjection.Extensions; +using Microsoft.AspNet.Mvc.Internal; +using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection { + /// + /// Extensions for configuring MVC using an . + /// public static class MvcCoreMvcBuilderExtensions { - public static IMvcBuilder AddFormatterMappings(this IMvcBuilder builder) - { - AddFormatterMappingsServices(builder.Services); - return builder; - } - public static IMvcBuilder AddFormatterMappings( - this IMvcBuilder builder, - Action setupAction) + [NotNull] this IMvcBuilder builder, + [NotNull] Action setupAction) { - AddFormatterMappingsServices(builder.Services); - - if (setupAction != null) - { - builder.Services.Configure((options) => setupAction(options.FormatterMappings)); - } - + builder.Services.Configure((options) => setupAction(options.FormatterMappings)); return builder; } - // Internal for testing. - internal static void AddFormatterMappingsServices(IServiceCollection services) + /// + /// Register the specified as services and as a source for controller + /// discovery. + /// + /// The . + /// A sequence of controller s to register in the + /// and used for controller discovery. + /// The . + public static IMvcBuilder AddControllersAsServices( + [NotNull] this IMvcBuilder builder, + [NotNull] IEnumerable controllerTypes) { - services.TryAddTransient(); - } - - public static IMvcBuilder AddAuthorization(this IMvcBuilder builder) - { - AddAuthorizationServices(builder.Services); + ControllersAsServices.AddControllersAsServices(builder.Services, controllerTypes); return builder; } - public static IMvcBuilder AddAuthorization(this IMvcBuilder builder, Action setupAction) + /// + /// Registers controller types from the specified as services and as a source + /// for controller discovery. + /// + /// The . + /// Assemblies to scan. + /// The . + public static IMvcBuilder AddControllersAsServices( + [NotNull] this IMvcBuilder builder, + [NotNull] IEnumerable controllerAssemblies) { - AddAuthorizationServices(builder.Services); - - if (setupAction != null) - { - builder.Services.Configure(setupAction); - } - + ControllersAsServices.AddControllersAsServices(builder.Services, controllerAssemblies); return builder; } - - // Internal for testing. - internal static void AddAuthorizationServices(IServiceCollection services) - { - services.AddAuthorization(); - - services.TryAddEnumerable( - ServiceDescriptor.Transient()); - } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreMvcCoreBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreMvcCoreBuilderExtensions.cs new file mode 100644 index 0000000000..3df61d043f --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreMvcCoreBuilderExtensions.cs @@ -0,0 +1,104 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.AspNet.Authorization; +using Microsoft.AspNet.Mvc; +using Microsoft.AspNet.Mvc.ApplicationModels; +using Microsoft.AspNet.Mvc.Internal; +using Microsoft.Framework.DependencyInjection.Extensions; +using Microsoft.Framework.Internal; + +namespace Microsoft.Framework.DependencyInjection +{ + public static class MvcCoreMvcCoreBuilderExtensions + { + public static IMvcCoreBuilder AddFormatterMappings(this IMvcCoreBuilder builder) + { + AddFormatterMappingsServices(builder.Services); + return builder; + } + + public static IMvcCoreBuilder AddFormatterMappings( + this IMvcCoreBuilder builder, + Action setupAction) + { + AddFormatterMappingsServices(builder.Services); + + if (setupAction != null) + { + builder.Services.Configure((options) => setupAction(options.FormatterMappings)); + } + + return builder; + } + + // Internal for testing. + internal static void AddFormatterMappingsServices(IServiceCollection services) + { + services.TryAddTransient(); + } + + public static IMvcCoreBuilder AddAuthorization(this IMvcCoreBuilder builder) + { + AddAuthorizationServices(builder.Services); + return builder; + } + + public static IMvcCoreBuilder AddAuthorization( + this IMvcCoreBuilder builder, + Action setupAction) + { + AddAuthorizationServices(builder.Services); + + if (setupAction != null) + { + builder.Services.Configure(setupAction); + } + + return builder; + } + + // Internal for testing. + internal static void AddAuthorizationServices(IServiceCollection services) + { + services.AddAuthorization(); + + services.TryAddEnumerable( + ServiceDescriptor.Transient()); + } + + /// + /// Register the specified as services and as a source for controller + /// discovery. + /// + /// The . + /// A sequence of controller s to register in the + /// and used for controller discovery. + /// The . + public static IMvcCoreBuilder AddControllersAsServices( + [NotNull] this IMvcCoreBuilder builder, + [NotNull] IEnumerable controllerTypes) + { + ControllersAsServices.AddControllersAsServices(builder.Services, controllerTypes); + return builder; + } + + /// + /// Registers controller types from the specified as services and as a source + /// for controller discovery. + /// + /// The . + /// Assemblies to scan. + /// The . + public static IMvcCoreBuilder AddControllersAsServices( + [NotNull] this IMvcCoreBuilder builder, + [NotNull] IEnumerable controllerAssemblies) + { + ControllersAsServices.AddControllersAsServices(builder.Services, controllerAssemblies); + return builder; + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreServiceCollectionExtensions.cs index 41ff87d837..35cb1d1603 100644 --- a/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreServiceCollectionExtensions.cs @@ -21,38 +21,25 @@ namespace Microsoft.Framework.DependencyInjection { public static class MvcCoreServiceCollectionExtensions { - public static IMvcBuilder AddMvcCore([NotNull] this IServiceCollection services) + public static IMvcCoreBuilder AddMvcCore([NotNull] this IServiceCollection services) + { + return AddMvcCore(services, setupAction: null); + } + + public static IMvcCoreBuilder AddMvcCore( + [NotNull] this IServiceCollection services, + Action setupAction) { ConfigureDefaultServices(services); AddMvcCoreServices(services); - return new MvcBuilder() { Services = services, }; - } + if (setupAction != null) + { + services.Configure(setupAction); + } - public static IMvcBuilder AddMvcCore( - [NotNull] this IServiceCollection services, - [NotNull] Action setupAction) - { - ConfigureDefaultServices(services); - - AddMvcCoreServices(services); - - services.Configure(setupAction); - - return new MvcBuilder() { Services = services, }; - } - - /// - /// Configures a set of for the application. - /// - /// The services available in the application. - /// The which need to be configured. - public static void ConfigureMvc( - [NotNull] this IServiceCollection services, - [NotNull] Action setupAction) - { - services.Configure(setupAction); + return new MvcCoreBuilder(services); } // To enable unit testing @@ -147,10 +134,5 @@ namespace Microsoft.Framework.DependencyInjection services.AddRouting(); services.AddNotifier(); } - - private class MvcBuilder : IMvcBuilder - { - public IServiceCollection Services { get; set; } - } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/FixedSetControllerTypeProvider.cs b/src/Microsoft.AspNet.Mvc.Core/FixedSetControllerTypeProvider.cs index 9df3118a81..c38d90588f 100644 --- a/src/Microsoft.AspNet.Mvc.Core/FixedSetControllerTypeProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/FixedSetControllerTypeProvider.cs @@ -35,6 +35,7 @@ namespace Microsoft.AspNet.Mvc /// public IList ControllerTypes { get; } + /// IEnumerable IControllerTypeProvider.ControllerTypes => ControllerTypes; } } diff --git a/src/Microsoft.AspNet.Mvc.Core/Internal/ControllersAsServices.cs b/src/Microsoft.AspNet.Mvc.Core/Internal/ControllersAsServices.cs new file mode 100644 index 0000000000..52f95d8902 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Internal/ControllersAsServices.cs @@ -0,0 +1,42 @@ +// 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 System.Reflection; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.DependencyInjection.Extensions; + +namespace Microsoft.AspNet.Mvc.Internal +{ + public static class ControllersAsServices + { + public static void AddControllersAsServices(IServiceCollection services, IEnumerable types) + { + var controllerTypeProvider = new FixedSetControllerTypeProvider(); + foreach (var type in types) + { + services.TryAddTransient(type, type); + controllerTypeProvider.ControllerTypes.Add(type.GetTypeInfo()); + } + + services.Replace(ServiceDescriptor.Transient()); + services.Replace(ServiceDescriptor.Instance(controllerTypeProvider)); + } + + public static void AddControllersAsServices(IServiceCollection services, IEnumerable assemblies) + { + var assemblyProvider = new FixedSetAssemblyProvider(); + foreach (var assembly in assemblies) + { + assemblyProvider.CandidateAssemblies.Add(assembly); + } + + var controllerTypeProvider = new DefaultControllerTypeProvider(assemblyProvider); + var controllerTypes = controllerTypeProvider.ControllerTypes; + + AddControllersAsServices(services, controllerTypes.Select(type => type.AsType())); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/Internal/MvcBuilder.cs b/src/Microsoft.AspNet.Mvc.Core/Internal/MvcBuilder.cs new file mode 100644 index 0000000000..742f58bd99 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Internal/MvcBuilder.cs @@ -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. + +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.Internal; + +namespace Microsoft.AspNet.Mvc.Internal +{ + public class MvcBuilder : IMvcBuilder + { + public MvcBuilder([NotNull] IServiceCollection services) + { + Services = services; + } + + public IServiceCollection Services { get; } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Internal/MvcCoreBuilder.cs b/src/Microsoft.AspNet.Mvc.Core/Internal/MvcCoreBuilder.cs new file mode 100644 index 0000000000..43ee424535 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Internal/MvcCoreBuilder.cs @@ -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. + +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.Internal; + +namespace Microsoft.AspNet.Mvc.Internal +{ + public class MvcCoreBuilder : IMvcCoreBuilder + { + public MvcCoreBuilder([NotNull] IServiceCollection services) + { + Services = services; + } + + public IServiceCollection Services { get; } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Cors/DependencyInjection/MvcCorsMvcBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.Cors/DependencyInjection/MvcCorsMvcCoreBuilderExtensions.cs similarity index 79% rename from src/Microsoft.AspNet.Mvc.Cors/DependencyInjection/MvcCorsMvcBuilderExtensions.cs rename to src/Microsoft.AspNet.Mvc.Cors/DependencyInjection/MvcCorsMvcCoreBuilderExtensions.cs index b579686b48..d81205cf5b 100644 --- a/src/Microsoft.AspNet.Mvc.Cors/DependencyInjection/MvcCorsMvcBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.Cors/DependencyInjection/MvcCorsMvcCoreBuilderExtensions.cs @@ -10,16 +10,16 @@ using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection { - public static class MvcCorsMvcBuilderExtensions + public static class MvcCorsMvcCoreBuilderExtensions { - public static IMvcBuilder AddCors([NotNull] this IMvcBuilder builder) + public static IMvcCoreBuilder AddCors([NotNull] this IMvcCoreBuilder builder) { AddCorsServices(builder.Services); return builder; } - public static IMvcBuilder AddCors( - [NotNull] this IMvcBuilder builder, + public static IMvcCoreBuilder AddCors( + [NotNull] this IMvcCoreBuilder builder, [NotNull] Action setupAction) { AddCorsServices(builder.Services); @@ -32,8 +32,8 @@ namespace Microsoft.Framework.DependencyInjection return builder; } - public static IMvcBuilder ConfigureCors( - [NotNull] this IMvcBuilder builder, + public static IMvcCoreBuilder ConfigureCors( + [NotNull] this IMvcCoreBuilder builder, [NotNull] Action setupAction) { builder.Services.Configure(setupAction); diff --git a/src/Microsoft.AspNet.Mvc.DataAnnotations/DependencyInjection/MvcDataAnnotationsMvcBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.DataAnnotations/DependencyInjection/MvcDataAnnotationsMvcCoreBuilderExtensions.cs similarity index 82% rename from src/Microsoft.AspNet.Mvc.DataAnnotations/DependencyInjection/MvcDataAnnotationsMvcBuilderExtensions.cs rename to src/Microsoft.AspNet.Mvc.DataAnnotations/DependencyInjection/MvcDataAnnotationsMvcCoreBuilderExtensions.cs index b5fc264fd7..2268266648 100644 --- a/src/Microsoft.AspNet.Mvc.DataAnnotations/DependencyInjection/MvcDataAnnotationsMvcBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.DataAnnotations/DependencyInjection/MvcDataAnnotationsMvcCoreBuilderExtensions.cs @@ -8,9 +8,9 @@ using Microsoft.Framework.OptionsModel; namespace Microsoft.Framework.DependencyInjection { - public static class MvcDataAnnotationsMvcBuilderExtensions + public static class MvcDataAnnotationsMvcCoreBuilderExtensions { - public static IMvcBuilder AddDataAnnotations([NotNull] this IMvcBuilder builder) + public static IMvcCoreBuilder AddDataAnnotations([NotNull] this IMvcCoreBuilder builder) { AddDataAnnotationsServices(builder.Services); return builder; diff --git a/src/Microsoft.AspNet.Mvc.Formatters.Json/DependencyInjection/MvcJsonMvcBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.Formatters.Json/DependencyInjection/MvcJsonMvcBuilderExtensions.cs index b67e03de79..0347c493a0 100644 --- a/src/Microsoft.AspNet.Mvc.Formatters.Json/DependencyInjection/MvcJsonMvcBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.Formatters.Json/DependencyInjection/MvcJsonMvcBuilderExtensions.cs @@ -3,48 +3,26 @@ using System; using Microsoft.AspNet.Mvc; -using Microsoft.Framework.DependencyInjection.Extensions; using Microsoft.Framework.Internal; -using Microsoft.Framework.OptionsModel; -using Newtonsoft.Json; namespace Microsoft.Framework.DependencyInjection { + /// + /// Extensions methods for configuring MVC via an . + /// public static class MvcJsonMvcBuilderExtensions { - public static IMvcBuilder AddJsonFormatters([NotNull] this IMvcBuilder builder) - { - AddJsonFormatterServices(builder.Services); - return builder; - } - - public static IMvcBuilder AddJsonFormatters( - [NotNull] this IMvcBuilder builder, - [NotNull] Action setupAction) - { - AddJsonFormatterServices(builder.Services); - - if (setupAction != null) - { - builder.Services.Configure((options) => setupAction(options.SerializerSettings)); - } - - return builder; - } - - public static IMvcBuilder ConfigureJson( + /// + /// Adds configuration of for the application. + /// + /// The . + /// The which need to be configured. + public static IMvcBuilder AddJsonOptions( [NotNull] this IMvcBuilder builder, [NotNull] Action setupAction) { builder.Services.Configure(setupAction); return builder; } - - // Internal for testing. - internal static void AddJsonFormatterServices(IServiceCollection services) - { - services.TryAddEnumerable( - ServiceDescriptor.Transient, MvcJsonMvcOptionsSetup>()); - } } } diff --git a/src/Microsoft.AspNet.Mvc.Formatters.Json/DependencyInjection/MvcJsonMvcCoreBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.Formatters.Json/DependencyInjection/MvcJsonMvcCoreBuilderExtensions.cs new file mode 100644 index 0000000000..20559ee388 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Formatters.Json/DependencyInjection/MvcJsonMvcCoreBuilderExtensions.cs @@ -0,0 +1,42 @@ +// 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; +using Microsoft.Framework.DependencyInjection.Extensions; +using Microsoft.Framework.Internal; +using Microsoft.Framework.OptionsModel; +using Newtonsoft.Json; + +namespace Microsoft.Framework.DependencyInjection +{ + public static class MvcJsonMvcCoreBuilderExtensions + { + public static IMvcCoreBuilder AddJsonFormatters([NotNull] this IMvcCoreBuilder builder) + { + AddJsonFormatterServices(builder.Services); + return builder; + } + + public static IMvcCoreBuilder AddJsonFormatters( + [NotNull] this IMvcCoreBuilder builder, + [NotNull] Action setupAction) + { + AddJsonFormatterServices(builder.Services); + + if (setupAction != null) + { + builder.Services.Configure((options) => setupAction(options.SerializerSettings)); + } + + return builder; + } + + // Internal for testing. + internal static void AddJsonFormatterServices(IServiceCollection services) + { + services.TryAddEnumerable( + ServiceDescriptor.Transient, MvcJsonMvcOptionsSetup>()); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Formatters.Xml/DependencyInjection/MvcXmlMvcCoreBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.Formatters.Xml/DependencyInjection/MvcXmlMvcCoreBuilderExtensions.cs new file mode 100644 index 0000000000..d0670295aa --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Formatters.Xml/DependencyInjection/MvcXmlMvcCoreBuilderExtensions.cs @@ -0,0 +1,52 @@ +// 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.Mvc; +using Microsoft.Framework.DependencyInjection.Extensions; +using Microsoft.Framework.Internal; +using Microsoft.Framework.OptionsModel; + +namespace Microsoft.Framework.DependencyInjection +{ + /// + /// Extension methods for adding XML formatters to MVC. + /// + public static class MvcXmlMvcCoreBuilderExtensions + { + /// + /// Adds the XML DataContractSerializer formatters to MVC. + /// + /// The . + /// The . + public static IMvcCoreBuilder AddXmlDataContractSerializerFormatters([NotNull] this IMvcCoreBuilder builder) + { + AddXmlDataContractSerializerFormatterServices(builder.Services); + return builder; + } + + /// + /// Adds the XML Serializer formatters to MVC. + /// + /// The . + /// The . + public static IMvcCoreBuilder AddXmlSerializerFormatters([NotNull] this IMvcCoreBuilder builder) + { + AddXmlSerializerFormatterServices(builder.Services); + return builder; + } + + // Internal for testing. + internal static void AddXmlDataContractSerializerFormatterServices(IServiceCollection services) + { + services.TryAddEnumerable( + ServiceDescriptor.Transient, MvcXmlDataContractSerializerMvcOptionsSetup>()); + } + + // Internal for testing. + internal static void AddXmlSerializerFormatterServices(IServiceCollection services) + { + services.TryAddEnumerable( + ServiceDescriptor.Transient, MvcXmlSerializerMvcOptionsSetup>()); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Formatters.Xml/MvcOptionsExtensions.cs b/src/Microsoft.AspNet.Mvc.Formatters.Xml/MvcOptionsExtensions.cs deleted file mode 100644 index c25265e3b1..0000000000 --- a/src/Microsoft.AspNet.Mvc.Formatters.Xml/MvcOptionsExtensions.cs +++ /dev/null @@ -1,21 +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 Microsoft.Framework.Internal; - -namespace Microsoft.AspNet.Mvc -{ - public static class MvcOptionsExtensions - { - /// - /// Adds and - /// to the - /// input and output formatter collections respectively. - /// - /// The MvcOptions - public static void AddXmlDataContractSerializerFormatter([NotNull] this MvcOptions options) - { - MvcXmlDataContractSerializerMvcOptionsSetup.ConfigureMvc(options); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Localization/DependencyInjection/MvcLocalizationMvcBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.Localization/DependencyInjection/MvcLocalizationMvcBuilderExtensions.cs index c51255ca26..bcd02cfe3a 100644 --- a/src/Microsoft.AspNet.Mvc.Localization/DependencyInjection/MvcLocalizationMvcBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.Localization/DependencyInjection/MvcLocalizationMvcBuilderExtensions.cs @@ -1,8 +1,14 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Linq; +using Microsoft.AspNet.Mvc; +using Microsoft.AspNet.Mvc.Localization; +using Microsoft.AspNet.Mvc.Localization.Internal; using Microsoft.AspNet.Mvc.Razor; +using Microsoft.Framework.DependencyInjection.Extensions; using Microsoft.Framework.Internal; +using Microsoft.Framework.WebEncoders; namespace Microsoft.Framework.DependencyInjection { @@ -16,14 +22,9 @@ namespace Microsoft.Framework.DependencyInjection /// /// The . /// The . - /// - /// Adding localization also adds support for views via - /// and the Razor view engine - /// via . - /// - public static IMvcBuilder AddLocalization([NotNull] this IMvcBuilder builder) + public static IMvcBuilder AddViewLocalization([NotNull] this IMvcBuilder builder) { - return AddLocalization(builder, LanguageViewLocationExpanderFormat.Suffix); + return AddViewLocalization(builder, LanguageViewLocationExpanderFormat.Suffix); } /// @@ -32,20 +33,11 @@ namespace Microsoft.Framework.DependencyInjection /// The . /// The view format for localized views. /// The . - /// - /// Adding localization also adds support for views via - /// and the Razor view engine - /// via . - /// - public static IMvcBuilder AddLocalization( + public static IMvcBuilder AddViewLocalization( [NotNull] this IMvcBuilder builder, LanguageViewLocationExpanderFormat format) { - - builder.AddViews(); - builder.AddRazorViewEngine(); - - MvcLocalizationServiceCollectionExtensions.AddMvcLocalization(builder.Services, format); + MvcLocalizationServices.AddLocalizationServices(builder.Services, format); return builder; } } diff --git a/src/Microsoft.AspNet.Mvc.Localization/DependencyInjection/MvcLocalizationMvcCoreBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.Localization/DependencyInjection/MvcLocalizationMvcCoreBuilderExtensions.cs new file mode 100644 index 0000000000..dc8108c451 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Localization/DependencyInjection/MvcLocalizationMvcCoreBuilderExtensions.cs @@ -0,0 +1,53 @@ +// 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.Mvc.Localization.Internal; +using Microsoft.AspNet.Mvc.Razor; +using Microsoft.Framework.Internal; + +namespace Microsoft.Framework.DependencyInjection +{ + /// + /// Extension methods for configuring MVC view localization. + /// + public static class MvcLocalizationMvcCoreBuilderExtensions + { + /// + /// Adds MVC localization to the application. + /// + /// The . + /// The . + /// + /// Adding localization also adds support for views via + /// and the Razor view engine + /// via . + /// + public static IMvcCoreBuilder AddViewLocalization([NotNull] this IMvcCoreBuilder builder) + { + return AddViewLocalization(builder, LanguageViewLocationExpanderFormat.Suffix); + } + + /// + /// Adds MVC localization to the application. + /// + /// The . + /// The view format for localized views. + /// The . + /// + /// Adding localization also adds support for views via + /// and the Razor view engine + /// via . + /// + public static IMvcCoreBuilder AddViewLocalization( + [NotNull] this IMvcCoreBuilder builder, + LanguageViewLocationExpanderFormat format) + { + + builder.AddViews(); + builder.AddRazorViewEngine(); + + MvcLocalizationServices.AddLocalizationServices(builder.Services, format); + return builder; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Localization/DependencyInjection/MvcLocalizationServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Mvc.Localization/DependencyInjection/MvcLocalizationServiceCollectionExtensions.cs deleted file mode 100644 index b4e619d364..0000000000 --- a/src/Microsoft.AspNet.Mvc.Localization/DependencyInjection/MvcLocalizationServiceCollectionExtensions.cs +++ /dev/null @@ -1,56 +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.Linq; -using Microsoft.AspNet.Mvc; -using Microsoft.AspNet.Mvc.Localization; -using Microsoft.AspNet.Mvc.Razor; -using Microsoft.Framework.DependencyInjection.Extensions; -using Microsoft.Framework.Internal; -using Microsoft.Framework.WebEncoders; - -namespace Microsoft.Framework.DependencyInjection -{ - /// - /// Extension methods for configuring MVC view localization. - /// - public static class MvcLocalizationServiceCollectionExtensions - { - /// - /// Adds MVC localization to the application. - /// - /// The . - /// The . - public static IServiceCollection AddMvcLocalization([NotNull] this IServiceCollection services) - { - return AddMvcLocalization(services, LanguageViewLocationExpanderFormat.Suffix); - } - - /// - /// Adds MVC localization to the application. - /// - /// The . - /// The view format for localized views. - /// The . - public static IServiceCollection AddMvcLocalization( - [NotNull] this IServiceCollection services, - LanguageViewLocationExpanderFormat format) - { - services.Configure( - options => - { - options.ViewLocationExpanders.Add(new LanguageViewLocationExpander(format)); - }, - DefaultOrder.DefaultFrameworkSortOrder); - - services.TryAdd(ServiceDescriptor.Singleton()); - services.TryAdd(ServiceDescriptor.Transient(typeof(IHtmlLocalizer<>), typeof(HtmlLocalizer<>))); - services.TryAdd(ServiceDescriptor.Transient()); - if (!services.Any(sd => sd.ServiceType == typeof(IHtmlEncoder))) - { - services.TryAdd(ServiceDescriptor.Instance(HtmlEncoder.Default)); - } - return services.AddLocalization(); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Localization/Internal/MvcLocalizationServices.cs b/src/Microsoft.AspNet.Mvc.Localization/Internal/MvcLocalizationServices.cs new file mode 100644 index 0000000000..044cafc0c6 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Localization/Internal/MvcLocalizationServices.cs @@ -0,0 +1,36 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Linq; +using Microsoft.AspNet.Mvc.Razor; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.DependencyInjection.Extensions; +using Microsoft.Framework.WebEncoders; + +namespace Microsoft.AspNet.Mvc.Localization.Internal +{ + public static class MvcLocalizationServices + { + public static void AddLocalizationServices( + IServiceCollection services, + LanguageViewLocationExpanderFormat format) + { + services.Configure( + options => + { + options.ViewLocationExpanders.Add(new LanguageViewLocationExpander(format)); + }, + DefaultOrder.DefaultFrameworkSortOrder); + + services.TryAdd(ServiceDescriptor.Singleton()); + services.TryAdd(ServiceDescriptor.Transient(typeof(IHtmlLocalizer<>), typeof(HtmlLocalizer<>))); + services.TryAdd(ServiceDescriptor.Transient()); + if (!services.Any(sd => sd.ServiceType == typeof(IHtmlEncoder))) + { + services.TryAdd(ServiceDescriptor.Instance(HtmlEncoder.Default)); + } + + services.AddLocalization(); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcBuilderExtensions.cs index d7ef1d50f0..79a7e10250 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcBuilderExtensions.cs @@ -1,71 +1,29 @@ -// 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.Linq; using System.Reflection; using Microsoft.AspNet.Mvc; using Microsoft.AspNet.Mvc.Razor; -using Microsoft.AspNet.Mvc.Razor.Compilation; -using Microsoft.AspNet.Mvc.Razor.Directives; -using Microsoft.AspNet.Mvc.Razor.Precompilation; -using Microsoft.Framework.Caching.Memory; +using Microsoft.AspNet.Mvc.Razor.Internal; +using Microsoft.AspNet.Razor.Runtime.TagHelpers; using Microsoft.Framework.DependencyInjection.Extensions; using Microsoft.Framework.Internal; -using Microsoft.Framework.OptionsModel; namespace Microsoft.Framework.DependencyInjection { + /// + /// Extensions methods for configuring MVC via an . + /// public static class MvcRazorMvcBuilderExtensions { - private static readonly Type RazorFileInfoCollectionType = typeof(RazorFileInfoCollection); - - public static IMvcBuilder AddRazorViewEngine([NotNull] this IMvcBuilder builder) - { - builder.AddViews(); - AddRazorViewEngineServices(builder.Services); - return builder; - } - - public static IMvcBuilder AddRazorViewEngine( - [NotNull] this IMvcBuilder builder, - [NotNull] Action setupAction) - { - builder.AddViews(); - AddRazorViewEngineServices(builder.Services); - - if (setupAction != null) - { - builder.Services.Configure(setupAction); - } - - return builder; - } - - public static IMvcBuilder AddPrecompiledRazorViews( - [NotNull] this IMvcBuilder builder, - [NotNull] params Assembly[] assemblies) - { - AddRazorViewEngine(builder); - - var razorFileInfos = GetFileInfoCollections(assemblies); - builder.Services.TryAddEnumerable(ServiceDescriptor.Instance(razorFileInfos)); - - return builder; - } - - public static IServiceCollection AddPrecompiledRazorViews( - [NotNull] this IServiceCollection collection, - [NotNull] params Assembly[] assemblies) - { - var razorFileInfos = GetFileInfoCollections(assemblies); - collection.TryAddEnumerable(ServiceDescriptor.Instance(razorFileInfos)); - - return collection; - } - - public static IMvcBuilder ConfigureRazorViewEngine( + /// + /// Configures a set of for the application. + /// + /// The . + /// An action to configure the . + /// The . + public static IMvcBuilder AddRazorOptions( [NotNull] this IMvcBuilder builder, [NotNull] Action setupAction) { @@ -73,64 +31,36 @@ namespace Microsoft.Framework.DependencyInjection return builder; } - // Internal for testing. - internal static void AddRazorViewEngineServices(IServiceCollection services) + /// + /// Adds an initialization callback for a given . + /// + /// + /// The callback will be invoked on any instance before the + /// method is called. + /// + /// The type of being initialized. + /// The instance this method extends. + /// An action to initialize the . + /// The instance this method extends. + public static IMvcBuilder InitializeTagHelper( + [NotNull] this IMvcBuilder builder, + [NotNull] Action initialize) + where TTagHelper : ITagHelper { - services.TryAddEnumerable( - ServiceDescriptor.Transient, MvcRazorMvcViewOptionsSetup>()); - services.TryAddEnumerable( - ServiceDescriptor.Transient, RazorViewEngineOptionsSetup>()); + var initializer = new TagHelperInitializer(initialize); - services.TryAddSingleton(); + builder.Services.AddInstance(typeof(ITagHelperInitializer), initializer); - // Caches view locations that are valid for the lifetime of the application. - services.TryAddSingleton(); - services.TryAdd(ServiceDescriptor.Singleton(serviceProvider => - { - var cachedFileProvider = serviceProvider.GetRequiredService>(); - return new DefaultChunkTreeCache(cachedFileProvider.Options.FileProvider); - })); - - // The host is designed to be discarded after consumption and is very inexpensive to initialize. - services.TryAddTransient(); - - // Caches compilation artifacts across the lifetime of the application. - services.TryAddSingleton(); - - // This caches compilation related details that are valid across the lifetime of the application - // and is required to be a singleton. - services.TryAddSingleton(); - - // Both the compiler cache and roslyn compilation service hold on the compilation related - // caches. RazorCompilation service is just an adapter service, and it is transient to ensure - // the IMvcRazorHost dependency does not maintain state. - services.TryAddTransient(); - - // The ViewStartProvider needs to be able to consume scoped instances of IRazorPageFactory - services.TryAddScoped(); - services.TryAddTransient(); - services.TryAddSingleton(); - - // Virtual path view factory needs to stay scoped so views can get get scoped services. - services.TryAddScoped(); - - // Only want one ITagHelperActivator so it can cache Type activation information. Types won't conflict. - services.TryAddSingleton(); - - // Consumed by the Cache tag helper to cache results across the lifetime of the application. - services.TryAddSingleton(); + return builder; + } + + public static IMvcBuilder AddPrecompiledRazorViews( + [NotNull] this IMvcBuilder builder, + [NotNull] params Assembly[] assemblies) + { + var razorFileInfos = RazorFileInfoCollections.GetFileInfoCollections(assemblies); + builder.Services.TryAddEnumerable(ServiceDescriptor.Instance(razorFileInfos)); + return builder; } - - private static IEnumerable GetFileInfoCollections(IEnumerable assemblies) => - assemblies - .SelectMany(assembly => assembly.ExportedTypes) - .Where(IsValidRazorFileInfoCollection) - .Select(Activator.CreateInstance) - .Cast(); - - internal static bool IsValidRazorFileInfoCollection(Type type) => - RazorFileInfoCollectionType.IsAssignableFrom(type) && - !type.GetTypeInfo().IsAbstract && - !type.GetTypeInfo().ContainsGenericParameters; } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs new file mode 100644 index 0000000000..8bf9a42c91 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs @@ -0,0 +1,126 @@ +// 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.Reflection; +using Microsoft.AspNet.Mvc; +using Microsoft.AspNet.Mvc.Razor; +using Microsoft.AspNet.Mvc.Razor.Compilation; +using Microsoft.AspNet.Mvc.Razor.Directives; +using Microsoft.AspNet.Mvc.Razor.Internal; +using Microsoft.AspNet.Razor.Runtime.TagHelpers; +using Microsoft.Framework.Caching.Memory; +using Microsoft.Framework.DependencyInjection.Extensions; +using Microsoft.Framework.Internal; +using Microsoft.Framework.OptionsModel; + +namespace Microsoft.Framework.DependencyInjection +{ + public static class MvcRazorMvcCoreBuilderExtensions + { + public static IMvcCoreBuilder AddRazorViewEngine([NotNull] this IMvcCoreBuilder builder) + { + builder.AddViews(); + AddRazorViewEngineServices(builder.Services); + return builder; + } + + public static IMvcCoreBuilder AddRazorViewEngine( + [NotNull] this IMvcCoreBuilder builder, + [NotNull] Action setupAction) + { + builder.AddViews(); + AddRazorViewEngineServices(builder.Services); + + if (setupAction != null) + { + builder.Services.Configure(setupAction); + } + + return builder; + } + + public static IMvcCoreBuilder AddPrecompiledRazorViews( + [NotNull] this IMvcCoreBuilder builder, + [NotNull] params Assembly[] assemblies) + { + AddRazorViewEngine(builder); + + var razorFileInfos = RazorFileInfoCollections.GetFileInfoCollections(assemblies); + builder.Services.TryAddEnumerable(ServiceDescriptor.Instance(razorFileInfos)); + + return builder; + } + + /// + /// Adds an initialization callback for a given . + /// + /// + /// The callback will be invoked on any instance before the + /// method is called. + /// + /// The type of being initialized. + /// The instance this method extends. + /// An action to initialize the . + /// The instance this method extends. + public static IMvcCoreBuilder InitializeTagHelper( + [NotNull] this IMvcCoreBuilder builder, + [NotNull] Action initialize) + where TTagHelper : ITagHelper + { + var initializer = new TagHelperInitializer(initialize); + + builder.Services.AddInstance(typeof(ITagHelperInitializer), initializer); + + return builder; + } + + // Internal for testing. + internal static void AddRazorViewEngineServices(IServiceCollection services) + { + services.TryAddEnumerable( + ServiceDescriptor.Transient, MvcRazorMvcViewOptionsSetup>()); + services.TryAddEnumerable( + ServiceDescriptor.Transient, RazorViewEngineOptionsSetup>()); + + services.TryAddSingleton(); + + // Caches view locations that are valid for the lifetime of the application. + services.TryAddSingleton(); + services.TryAdd(ServiceDescriptor.Singleton(serviceProvider => + { + var cachedFileProvider = serviceProvider.GetRequiredService>(); + return new DefaultChunkTreeCache(cachedFileProvider.Options.FileProvider); + })); + + // The host is designed to be discarded after consumption and is very inexpensive to initialize. + services.TryAddTransient(); + + // Caches compilation artifacts across the lifetime of the application. + services.TryAddSingleton(); + + // This caches compilation related details that are valid across the lifetime of the application + // and is required to be a singleton. + services.TryAddSingleton(); + + // Both the compiler cache and roslyn compilation service hold on the compilation related + // caches. RazorCompilation service is just an adapter service, and it is transient to ensure + // the IMvcRazorHost dependency does not maintain state. + services.TryAddTransient(); + + // The ViewStartProvider needs to be able to consume scoped instances of IRazorPageFactory + services.TryAddScoped(); + services.TryAddTransient(); + services.TryAddSingleton(); + + // Virtual path view factory needs to stay scoped so views can get get scoped services. + services.TryAddScoped(); + + // Only want one ITagHelperActivator so it can cache Type activation information. Types won't conflict. + services.TryAddSingleton(); + + // Consumed by the Cache tag helper to cache results across the lifetime of the application. + services.TryAddSingleton(); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Razor/Internal/RazorFileInfoCollections.cs b/src/Microsoft.AspNet.Mvc.Razor/Internal/RazorFileInfoCollections.cs new file mode 100644 index 0000000000..b7bb454743 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Razor/Internal/RazorFileInfoCollections.cs @@ -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.Generic; +using System.Linq; +using System.Reflection; +using Microsoft.AspNet.Mvc.Razor.Precompilation; + +namespace Microsoft.AspNet.Mvc.Razor.Internal +{ + public static class RazorFileInfoCollections + { + private static readonly Type RazorFileInfoCollectionType = typeof(RazorFileInfoCollection); + + public static IEnumerable GetFileInfoCollections(IEnumerable assemblies) + { + return assemblies + .SelectMany(assembly => assembly.ExportedTypes) + .Where(IsValidRazorFileInfoCollection) + .Select(Activator.CreateInstance) + .Cast(); + } + + + public static bool IsValidRazorFileInfoCollection(Type type) + { + return + RazorFileInfoCollectionType.IsAssignableFrom(type) && + !type.GetTypeInfo().IsAbstract && + !type.GetTypeInfo().ContainsGenericParameters; + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorServiceCollectionExtensions.cs deleted file mode 100644 index 460cd6e1a1..0000000000 --- a/src/Microsoft.AspNet.Mvc.Razor/RazorServiceCollectionExtensions.cs +++ /dev/null @@ -1,52 +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 Microsoft.AspNet.Mvc; -using Microsoft.AspNet.Mvc.Razor; -using Microsoft.AspNet.Razor.Runtime.TagHelpers; -using Microsoft.Framework.Internal; - -namespace Microsoft.Framework.DependencyInjection -{ - /// - /// Contains extension methods to . - /// - public static class ServiceCollectionExtensions - { - /// - /// Configures a set of for the application. - /// - /// The services available in the application. - /// An action to configure the . - public static void ConfigureRazorViewEngine( - [NotNull] this IServiceCollection services, - [NotNull] Action setupAction) - { - services.Configure(setupAction); - } - - /// - /// Adds an initialization callback for a given . - /// - /// - /// The callback will be invoked on any instance before the - /// method is called. - /// - /// The type of being initialized. - /// The instance this method extends. - /// An action to initialize the . - /// The instance this method extends. - public static IServiceCollection InitializeTagHelper( - [NotNull] this IServiceCollection services, - [NotNull] Action initialize) - where TTagHelper : ITagHelper - { - var initializer = new TagHelperInitializer(initialize); - - services.AddInstance(typeof(ITagHelperInitializer), initializer); - - return services; - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcBuilderExtensions.cs index beba3865d6..b355a16318 100644 --- a/src/Microsoft.AspNet.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcBuilderExtensions.cs @@ -3,111 +3,26 @@ using System; using Microsoft.AspNet.Mvc; -using Microsoft.AspNet.Mvc.Rendering; -using Microsoft.AspNet.Mvc.ViewComponents; -using Microsoft.Framework.DependencyInjection.Extensions; using Microsoft.Framework.Internal; -using Microsoft.Framework.OptionsModel; namespace Microsoft.Framework.DependencyInjection { + /// + /// Extensions methods for configuring MVC via an . + /// public static class MvcViewFeaturesMvcBuilderExtensions { - public static IMvcBuilder AddViews([NotNull] this IMvcBuilder builder) - { - builder.AddDataAnnotations(); - AddViewServices(builder.Services); - return builder; - } - - public static IMvcBuilder AddViews( - [NotNull] this IMvcBuilder builder, - [NotNull] Action setupAction) - { - builder.AddDataAnnotations(); - AddViewServices(builder.Services); - - if (setupAction != null) - { - builder.Services.Configure(setupAction); - } - - return builder; - } - - public static IMvcBuilder ConfigureViews( + /// + /// Adds configuration of for the application. + /// + /// The . + /// The which need to be configured. + public static IMvcBuilder AddViewOptions( [NotNull] this IMvcBuilder builder, [NotNull] Action setupAction) { builder.Services.Configure(setupAction); return builder; } - - // Internal for testing. - internal static void AddViewServices(IServiceCollection services) - { - services.AddDataProtection(); - services.AddAntiforgery(); - services.AddWebEncoders(); - - services.TryAddEnumerable( - ServiceDescriptor.Transient, MvcViewOptionsSetup>()); - services.TryAddEnumerable( - ServiceDescriptor.Transient, TempDataMvcOptionsSetup>()); - - // - // View Engine and related infrastructure - // - services.TryAddSingleton(); - - // Support for activating ViewDataDictionary - services.TryAddEnumerable( - ServiceDescriptor - .Transient()); - - // - // HTML Helper - // - services.TryAddTransient(); - services.TryAddTransient(typeof(IHtmlHelper<>), typeof(HtmlHelper<>)); - - // DefaultHtmlGenerator is pretty much stateless but depends on IUrlHelper, which is scoped. - // Therefore it too is scoped. - services.TryAddScoped(); - - // - // JSON Helper - // - services.TryAddSingleton(); - services.TryAdd(ServiceDescriptor.Singleton(serviceProvider => - { - var options = serviceProvider.GetRequiredService>().Options; - return new JsonOutputFormatter(options.SerializerSettings); - })); - - // - // View Components - // - // These do caching so they should stay singleton - services.TryAddSingleton(); - services.TryAddSingleton(); - services.TryAddSingleton< - IViewComponentDescriptorCollectionProvider, - DefaultViewComponentDescriptorCollectionProvider>(); - - services.TryAddTransient(); - services.TryAddSingleton(); - services.TryAddTransient(); - - // - // Temp Data - // - // Holds per-request data so it should be scoped - services.TryAddScoped(); - services.TryAddScoped(); - - // This does caching so it should stay singleton - services.TryAddSingleton(); - } } } diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcCoreBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcCoreBuilderExtensions.cs new file mode 100644 index 0000000000..805026572c --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcCoreBuilderExtensions.cs @@ -0,0 +1,113 @@ +// 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; +using Microsoft.AspNet.Mvc.Rendering; +using Microsoft.AspNet.Mvc.ViewComponents; +using Microsoft.Framework.DependencyInjection.Extensions; +using Microsoft.Framework.Internal; +using Microsoft.Framework.OptionsModel; + +namespace Microsoft.Framework.DependencyInjection +{ + public static class MvcViewFeaturesMvcCoreBuilderExtensions + { + public static IMvcCoreBuilder AddViews([NotNull] this IMvcCoreBuilder builder) + { + builder.AddDataAnnotations(); + AddViewServices(builder.Services); + return builder; + } + + public static IMvcCoreBuilder AddViews( + [NotNull] this IMvcCoreBuilder builder, + [NotNull] Action setupAction) + { + builder.AddDataAnnotations(); + AddViewServices(builder.Services); + + if (setupAction != null) + { + builder.Services.Configure(setupAction); + } + + return builder; + } + + public static IMvcCoreBuilder ConfigureViews( + [NotNull] this IMvcCoreBuilder builder, + [NotNull] Action setupAction) + { + builder.Services.Configure(setupAction); + return builder; + } + + // Internal for testing. + internal static void AddViewServices(IServiceCollection services) + { + services.AddDataProtection(); + services.AddAntiforgery(); + services.AddWebEncoders(); + + services.TryAddEnumerable( + ServiceDescriptor.Transient, MvcViewOptionsSetup>()); + services.TryAddEnumerable( + ServiceDescriptor.Transient, TempDataMvcOptionsSetup>()); + + // + // View Engine and related infrastructure + // + services.TryAddSingleton(); + + // Support for activating ViewDataDictionary + services.TryAddEnumerable( + ServiceDescriptor + .Transient()); + + // + // HTML Helper + // + services.TryAddTransient(); + services.TryAddTransient(typeof(IHtmlHelper<>), typeof(HtmlHelper<>)); + + // DefaultHtmlGenerator is pretty much stateless but depends on IUrlHelper, which is scoped. + // Therefore it too is scoped. + services.TryAddScoped(); + + // + // JSON Helper + // + services.TryAddSingleton(); + services.TryAdd(ServiceDescriptor.Singleton(serviceProvider => + { + var options = serviceProvider.GetRequiredService>().Options; + return new JsonOutputFormatter(options.SerializerSettings); + })); + + // + // View Components + // + // These do caching so they should stay singleton + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton< + IViewComponentDescriptorCollectionProvider, + DefaultViewComponentDescriptorCollectionProvider>(); + + services.TryAddTransient(); + services.TryAddSingleton(); + services.TryAddTransient(); + + // + // Temp Data + // + // Holds per-request data so it should be scoped + services.TryAddScoped(); + services.TryAddScoped(); + + // This does caching so it should stay singleton + services.TryAddSingleton(); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/WebApiCompatShimServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/WebApiCompatShimMvcBuilderExtensions.cs similarity index 67% rename from src/Microsoft.AspNet.Mvc.WebApiCompatShim/WebApiCompatShimServiceCollectionExtensions.cs rename to src/Microsoft.AspNet.Mvc.WebApiCompatShim/WebApiCompatShimMvcBuilderExtensions.cs index c8a4c5a77a..c36969fdca 100644 --- a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/WebApiCompatShimServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/WebApiCompatShimMvcBuilderExtensions.cs @@ -9,20 +9,20 @@ using Microsoft.Framework.OptionsModel; namespace Microsoft.Framework.DependencyInjection { - public static class WebApiCompatShimServiceCollectionExtensions + public static class WebApiCompatShimMvcBuilderExtensions { - public static IServiceCollection AddWebApiConventions(this IServiceCollection services) + public static IMvcBuilder AddWebApiConventions(this IMvcBuilder builder) { - services.TryAddEnumerable( + builder.Services.TryAddEnumerable( ServiceDescriptor.Transient, WebApiCompatShimOptionsSetup>()); - services.TryAddEnumerable( + builder.Services.TryAddEnumerable( ServiceDescriptor.Transient, WebApiCompatShimOptionsSetup>()); // The constructors on DefaultContentNegotiator aren't DI friendly, so just // new it up. - services.TryAdd(ServiceDescriptor.Instance(new DefaultContentNegotiator())); + builder.Services.TryAdd(ServiceDescriptor.Instance(new DefaultContentNegotiator())); - return services; + return builder; } } } diff --git a/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs index 0f9fb37c4e..89bdd09e3b 100644 --- a/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs @@ -2,18 +2,20 @@ // 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 System.Reflection; using Microsoft.AspNet.Mvc; -using Microsoft.Framework.DependencyInjection.Extensions; +using Microsoft.AspNet.Mvc.Internal; using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection { public static class MvcServiceCollectionExtensions { - public static IServiceCollection AddMvc([NotNull] this IServiceCollection services) + public static IMvcBuilder AddMvc([NotNull] this IServiceCollection services) + { + return AddMvc(services, setupAction: null); + } + + public static IMvcBuilder AddMvc([NotNull] this IServiceCollection services, Action setupAction) { var builder = services.AddMvcCore(); @@ -26,79 +28,12 @@ namespace Microsoft.Framework.DependencyInjection builder.AddViews(); builder.AddRazorViewEngine(); - return services; - } - - /// - /// Configures a set of for the application. - /// - /// The services available in the application. - /// The which need to be configured. - public static void ConfigureMvcViews( - [NotNull] this IServiceCollection services, - [NotNull] Action setupAction) - { - services.Configure(setupAction); - } - - /// - /// Configures a set of for the application. - /// - /// The services available in the application. - /// The which need to be configured. - public static void ConfigureMvcJson( - [NotNull] this IServiceCollection services, - [NotNull] Action setupAction) - { - services.Configure(setupAction); - } - - /// - /// Register the specified as services and as a source for controller - /// discovery. - /// - /// The . - /// A sequence of controller s to register in the - /// and used for controller discovery. - /// The . - public static IServiceCollection WithControllersAsServices( - [NotNull] this IServiceCollection services, - [NotNull] IEnumerable controllerTypes) - { - var controllerTypeProvider = new FixedSetControllerTypeProvider(); - foreach (var type in controllerTypes) + if (setupAction != null) { - services.TryAddTransient(type, type); - controllerTypeProvider.ControllerTypes.Add(type.GetTypeInfo()); + builder.Services.Configure(setupAction); } - services.Replace(ServiceDescriptor.Transient()); - services.Replace(ServiceDescriptor.Instance(controllerTypeProvider)); - - return services; - } - - /// - /// Registers controller types from the specified as services and as a source - /// for controller discovery. - /// - /// The . - /// Assemblies to scan. - /// The . - public static IServiceCollection WithControllersAsServices( - [NotNull] this IServiceCollection services, - [NotNull] IEnumerable controllerAssemblies) - { - var assemblyProvider = new FixedSetAssemblyProvider(); - foreach (var assembly in controllerAssemblies) - { - assemblyProvider.CandidateAssemblies.Add(assembly); - } - - var controllerTypeProvider = new DefaultControllerTypeProvider(assemblyProvider); - var controllerTypes = controllerTypeProvider.ControllerTypes; - - return WithControllersAsServices(services, controllerTypes.Select(type => type.AsType())); + return new MvcBuilder(services); } } } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/DepenencyInjection/MvcBuilderExtensionsTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/DepenencyInjection/MvcBuilderExtensionsTest.cs new file mode 100644 index 0000000000..bf4ecd332e --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.Core.Test/DepenencyInjection/MvcBuilderExtensionsTest.cs @@ -0,0 +1,71 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Linq; +using System.Reflection; +using Microsoft.AspNet.Mvc.MvcServiceCollectionExtensionsTestControllers; +using Microsoft.Framework.DependencyInjection; +using Moq; +using Xunit; + +namespace Microsoft.AspNet.Mvc +{ + public class MvcBuilderExtensionsTest + { + [Fact] + public void WithControllersAsServices_AddsTypesToControllerTypeProviderAndServiceCollection() + { + // Arrange + var builder = new Mock(); + var collection = new ServiceCollection(); + builder.SetupGet(b => b.Services).Returns(collection); + + var controllerTypes = new[] + { + typeof(ControllerTypeA).GetTypeInfo(), + typeof(TypeBController).GetTypeInfo(), + }; + + // Act + builder.Object.AddControllersAsServices(controllerTypes); + + // Assert + var services = collection.ToList(); + Assert.Equal(4, services.Count); + Assert.Equal(typeof(ControllerTypeA), services[0].ServiceType); + Assert.Equal(typeof(ControllerTypeA), services[0].ImplementationType); + Assert.Equal(ServiceLifetime.Transient, services[0].Lifetime); + + Assert.Equal(typeof(TypeBController), services[1].ServiceType); + Assert.Equal(typeof(TypeBController), services[1].ImplementationType); + Assert.Equal(ServiceLifetime.Transient, services[1].Lifetime); + + Assert.Equal(typeof(IControllerActivator), services[2].ServiceType); + Assert.Equal(typeof(ServiceBasedControllerActivator), services[2].ImplementationType); + Assert.Equal(ServiceLifetime.Transient, services[2].Lifetime); + + Assert.Equal(typeof(IControllerTypeProvider), services[3].ServiceType); + var typeProvider = Assert.IsType(services[3].ImplementationInstance); + Assert.Equal(controllerTypes, typeProvider.ControllerTypes.OrderBy(c => c.Name)); + Assert.Equal(ServiceLifetime.Singleton, services[3].Lifetime); + } + } +} + +// These controllers are used to test the UseControllersAsServices implementation +// which REQUIRES that they be public top-level classes. To avoid having to stub out the +// implementation of this class to test it, they are just top level classes. Don't reuse +// these outside this test - find a better way or use nested classes to keep the tests +// independent. +namespace Microsoft.AspNet.Mvc.MvcServiceCollectionExtensionsTestControllers +{ + public class ControllerTypeA : Controller + { + + } + + public class TypeBController + { + + } +} diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlGenerationTest.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlGenerationTest.cs index a5d4990fee..0af1109ca4 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlGenerationTest.cs +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlGenerationTest.cs @@ -11,6 +11,7 @@ using System.Reflection; using System.Threading.Tasks; using HtmlGenerationWebSite; using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Mvc.Internal; using Microsoft.AspNet.Mvc.TagHelpers; using Microsoft.AspNet.Testing; using Microsoft.Framework.DependencyInjection; @@ -502,7 +503,8 @@ Products: Laptops (3)"; { // Arrange var newServices = new ServiceCollection(); - newServices.InitializeTagHelper((helper, _) => helper.Antiforgery = optionsAntiforgery); + var builder = new MvcCoreBuilder(newServices); + builder.InitializeTagHelper((helper, _) => helper.Antiforgery = optionsAntiforgery); var server = TestHelper.CreateServer(_app, SiteName, services => { diff --git a/test/Microsoft.AspNet.Mvc.Localization.Test/DependencyInjection/MvcLocalizationServiceCollectionExtensionsTest.cs b/test/Microsoft.AspNet.Mvc.Localization.Test/Internal/MvcLocalizationServiceCollectionExtensionsTest.cs similarity index 92% rename from test/Microsoft.AspNet.Mvc.Localization.Test/DependencyInjection/MvcLocalizationServiceCollectionExtensionsTest.cs rename to test/Microsoft.AspNet.Mvc.Localization.Test/Internal/MvcLocalizationServiceCollectionExtensionsTest.cs index abd486edc6..735ced0d36 100644 --- a/test/Microsoft.AspNet.Mvc.Localization.Test/DependencyInjection/MvcLocalizationServiceCollectionExtensionsTest.cs +++ b/test/Microsoft.AspNet.Mvc.Localization.Test/Internal/MvcLocalizationServiceCollectionExtensionsTest.cs @@ -5,8 +5,8 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; -using Microsoft.AspNet.Mvc.Localization; using Microsoft.AspNet.Mvc.Razor; +using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection.Extensions; using Microsoft.Framework.Localization; using Microsoft.Framework.OptionsModel; @@ -14,18 +14,20 @@ using Microsoft.Framework.WebEncoders; using Microsoft.Framework.WebEncoders.Testing; using Xunit; -namespace Microsoft.Framework.DependencyInjection +namespace Microsoft.AspNet.Mvc.Localization.Internal { - public class MvcLocalizationServiceCollectionExtensionsTest + public class MvcLocalizationServicesTest { [Fact] - public void AddMvcLocalization_AddsNeededServices() + public void AddLocalizationServices_AddsNeededServices() { // Arrange var collection = new ServiceCollection(); // Act - MvcLocalizationServiceCollectionExtensions.AddMvcLocalization(collection); + MvcLocalizationServices.AddLocalizationServices( + collection, + LanguageViewLocationExpanderFormat.Suffix); // Assert var services = collection.ToList(); @@ -59,7 +61,7 @@ namespace Microsoft.Framework.DependencyInjection } [Fact] - public void AddCustomLocalizers_BeforeMvcLocalization_AddsNeededServices() + public void AddCustomLocalizers_BeforeAddLocalizationServices_AddsNeededServices() { // Arrange var collection = new ServiceCollection(); @@ -70,7 +72,9 @@ namespace Microsoft.Framework.DependencyInjection collection.Add(ServiceDescriptor.Transient(typeof(IViewLocalizer), typeof(TestViewLocalizer))); collection.Add(ServiceDescriptor.Instance(typeof(IHtmlEncoder), typeof(CommonTestEncoder))); - MvcLocalizationServiceCollectionExtensions.AddMvcLocalization(collection); + MvcLocalizationServices.AddLocalizationServices( + collection, + LanguageViewLocationExpanderFormat.Suffix); // Assert var services = collection.ToList(); @@ -94,7 +98,7 @@ namespace Microsoft.Framework.DependencyInjection } [Fact] - public void AddCustomLocalizers_AfterMvcLocalization_AddsNeededServices() + public void AddCustomLocalizers_AfterAddLocalizationServices_AddsNeededServices() { // Arrange var collection = new ServiceCollection(); @@ -105,7 +109,9 @@ namespace Microsoft.Framework.DependencyInjection }); // Act - MvcLocalizationServiceCollectionExtensions.AddMvcLocalization(collection); + MvcLocalizationServices.AddLocalizationServices( + collection, + LanguageViewLocationExpanderFormat.Suffix); collection.Add(ServiceDescriptor.Transient(typeof(IHtmlLocalizer<>), typeof(TestHtmlLocalizer<>))); collection.Add(ServiceDescriptor.Transient(typeof(IHtmlLocalizer), typeof(TestViewLocalizer))); diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/DefaultTagHelperActivatorTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/DefaultTagHelperActivatorTest.cs index 842f93c274..aff0ba923f 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/DefaultTagHelperActivatorTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/DefaultTagHelperActivatorTest.cs @@ -5,6 +5,7 @@ using System; using System.IO; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Internal; +using Microsoft.AspNet.Mvc.Internal; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Razor.Runtime.TagHelpers; @@ -24,7 +25,8 @@ namespace Microsoft.AspNet.Mvc.Razor { // Arrange var services = new ServiceCollection(); - services.InitializeTagHelper((h, vc) => + var builder = new MvcCoreBuilder(services); + builder.InitializeTagHelper((h, vc) => { h.Name = name; h.Number = number; @@ -51,7 +53,8 @@ namespace Microsoft.AspNet.Mvc.Razor { // Arrange var services = new ServiceCollection(); - services.InitializeTagHelper((h, _) => h.ViewContext = MakeViewContext(MakeHttpContext())); + var builder = new MvcCoreBuilder(services); + builder.InitializeTagHelper((h, _) => h.ViewContext = MakeViewContext(MakeHttpContext())); var httpContext = MakeHttpContext(services.BuildServiceProvider()); var viewContext = MakeViewContext(httpContext); var activator = new DefaultTagHelperActivator(); @@ -69,12 +72,13 @@ namespace Microsoft.AspNet.Mvc.Razor { // Arrange var services = new ServiceCollection(); - services.InitializeTagHelper((h, vc) => + var builder = new MvcCoreBuilder(services); + builder.InitializeTagHelper((h, vc) => { h.Name = "Test 1"; h.Number = 100; }); - services.InitializeTagHelper((h, vc) => + builder.InitializeTagHelper((h, vc) => { h.Name += ", Test 2"; h.Number += 100; @@ -97,12 +101,13 @@ namespace Microsoft.AspNet.Mvc.Razor { // Arrange var services = new ServiceCollection(); - services.InitializeTagHelper((h, vc) => + var builder = new MvcCoreBuilder(services); + builder.InitializeTagHelper((h, vc) => { h.Name = "Test 1"; h.Number = 100; }); - services.InitializeTagHelper((h, vc) => + builder.InitializeTagHelper((h, vc) => { h.Name = "Test 2"; h.Number = 102; diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/DependencyInjection/MvcRazorMvcBuilderExtensionsTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/Internal/RazorFileInfoCollectionsTest.cs similarity index 83% rename from test/Microsoft.AspNet.Mvc.Razor.Test/DependencyInjection/MvcRazorMvcBuilderExtensionsTest.cs rename to test/Microsoft.AspNet.Mvc.Razor.Test/Internal/RazorFileInfoCollectionsTest.cs index 46c33cff8d..51d7d7812e 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/DependencyInjection/MvcRazorMvcBuilderExtensionsTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/Internal/RazorFileInfoCollectionsTest.cs @@ -3,12 +3,13 @@ using System; using Microsoft.AspNet.Mvc; +using Microsoft.AspNet.Mvc.Razor.Internal; using Microsoft.AspNet.Mvc.Razor.Precompilation; using Xunit; namespace Microsoft.Framework.DependencyInjection { - public class MvcRazorMvcBuilderExtensionsTest + public class RazorFileInfoCollectionsTest { [Fact] public void IsValidRazorFileInfoCollection_ReturnsFalse_IfTypeIsAbstract() @@ -17,7 +18,7 @@ namespace Microsoft.Framework.DependencyInjection var type = typeof(AbstractRazorFileInfoCollection); // Act - var result = MvcRazorMvcBuilderExtensions.IsValidRazorFileInfoCollection(type); + var result = RazorFileInfoCollections.IsValidRazorFileInfoCollection(type); // Assert Assert.False(result); @@ -30,7 +31,7 @@ namespace Microsoft.Framework.DependencyInjection var type = typeof(GenericRazorFileInfoCollection<>); // Act - var result = MvcRazorMvcBuilderExtensions.IsValidRazorFileInfoCollection(type); + var result = RazorFileInfoCollections.IsValidRazorFileInfoCollection(type); // Assert Assert.False(result); @@ -43,7 +44,7 @@ namespace Microsoft.Framework.DependencyInjection var type = typeof(NonSubTypeRazorFileInfoCollection); // Act - var result = MvcRazorMvcBuilderExtensions.IsValidRazorFileInfoCollection(type); + var result = RazorFileInfoCollections.IsValidRazorFileInfoCollection(type); // Assert Assert.False(result); @@ -55,7 +56,7 @@ namespace Microsoft.Framework.DependencyInjection public void IsValidRazorFileInfoCollection_ReturnsTrue_IfTypeDerivesFromRazorFileInfoCollection(Type type) { // Act - var result = MvcRazorMvcBuilderExtensions.IsValidRazorFileInfoCollection(type); + var result = RazorFileInfoCollections.IsValidRazorFileInfoCollection(type); // Assert Assert.True(result); diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewEngineOptionsTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewEngineOptionsTest.cs index 2e871afdff..104777013d 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewEngineOptionsTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewEngineOptionsTest.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Microsoft.AspNet.Mvc.Internal; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; using Xunit; @@ -22,14 +23,15 @@ namespace Microsoft.AspNet.Mvc.Razor } [Fact] - public void ConfigureRazorViewEngine_ConfiguresOptionsProperly() + public void AddRazorOptions_ConfiguresOptionsProperly() { // Arrange var services = new ServiceCollection().AddOptions(); var fileProvider = new TestFileProvider(); // Act - services.ConfigureRazorViewEngine(options => + var builder = new MvcBuilder(services); + builder.AddRazorOptions(options => { options.FileProvider = fileProvider; }); diff --git a/test/Microsoft.AspNet.Mvc.Test/MvcOptionsSetupTest.cs b/test/Microsoft.AspNet.Mvc.Test/MvcOptionsSetupTest.cs index ce765b564a..7da30076d3 100644 --- a/test/Microsoft.AspNet.Mvc.Test/MvcOptionsSetupTest.cs +++ b/test/Microsoft.AspNet.Mvc.Test/MvcOptionsSetupTest.cs @@ -5,6 +5,7 @@ using System; using System.IO; using System.Linq; using System.Xml.Linq; +using Microsoft.AspNet.Mvc.Internal; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.Razor; @@ -134,7 +135,11 @@ namespace Microsoft.AspNet.Mvc public void Setup_SetsUpExcludeFromValidationDelegates() { // Arrange & Act - var options = GetOptions(_ => _.ConfigureMvc(o => o.AddXmlDataContractSerializerFormatter())); + var options = GetOptions(services => + { + var builder = new MvcCoreBuilder(services); + builder.AddXmlDataContractSerializerFormatters(); + }); // Assert Assert.Equal(8, options.ValidationExcludeFilters.Count); diff --git a/test/Microsoft.AspNet.Mvc.Test/MvcServiceCollectionExtensionsTest.cs b/test/Microsoft.AspNet.Mvc.Test/MvcServiceCollectionExtensionsTest.cs index 91b7544f41..7f7e1d762b 100644 --- a/test/Microsoft.AspNet.Mvc.Test/MvcServiceCollectionExtensionsTest.cs +++ b/test/Microsoft.AspNet.Mvc.Test/MvcServiceCollectionExtensionsTest.cs @@ -10,7 +10,6 @@ using Microsoft.AspNet.Mvc.ApiExplorer; using Microsoft.AspNet.Mvc.ApplicationModels; using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.Filters; -using Microsoft.AspNet.Mvc.MvcServiceCollectionExtensionsTestControllers; using Microsoft.AspNet.Mvc.Razor; using Microsoft.AspNet.Routing; using Microsoft.Framework.DependencyInjection; @@ -23,71 +22,6 @@ namespace Microsoft.AspNet.Mvc { public class MvcServiceCollectionExtensionsTest { - [Fact] - public void WithControllersAsServices_AddsTypesToControllerTypeProviderAndServiceCollection() - { - // Arrange - var collection = new ServiceCollection(); - var controllerTypes = new[] { typeof(ControllerTypeA).GetTypeInfo(), typeof(TypeBController).GetTypeInfo() }; - - // Act - MvcServiceCollectionExtensions.WithControllersAsServices(collection, - controllerTypes); - - // Assert - var services = collection.ToList(); - Assert.Equal(4, services.Count); - Assert.Equal(typeof(ControllerTypeA), services[0].ServiceType); - Assert.Equal(typeof(ControllerTypeA), services[0].ImplementationType); - Assert.Equal(ServiceLifetime.Transient, services[0].Lifetime); - - Assert.Equal(typeof(TypeBController), services[1].ServiceType); - Assert.Equal(typeof(TypeBController), services[1].ImplementationType); - Assert.Equal(ServiceLifetime.Transient, services[1].Lifetime); - - Assert.Equal(typeof(IControllerActivator), services[2].ServiceType); - Assert.Equal(typeof(ServiceBasedControllerActivator), services[2].ImplementationType); - Assert.Equal(ServiceLifetime.Transient, services[2].Lifetime); - - Assert.Equal(typeof(IControllerTypeProvider), services[3].ServiceType); - var typeProvider = Assert.IsType(services[3].ImplementationInstance); - Assert.Equal(controllerTypes, typeProvider.ControllerTypes.OrderBy(c => c.Name)); - Assert.Equal(ServiceLifetime.Singleton, services[3].Lifetime); - } - - [Fact] - public void WithControllersAsServices_ScansControllersFromSpecifiedAssemblies() - { - // Arrange - var collection = new ServiceCollection(); - var assemblies = new[] { GetType().Assembly }; - var controllerTypes = new[] { typeof(ControllerTypeA), typeof(TypeBController) }; - - // Act - MvcServiceCollectionExtensions.WithControllersAsServices(collection, assemblies); - - // Assert - var services = collection.ToList(); - Assert.Equal(4, services.Count); - Assert.Equal(typeof(ControllerTypeA), services[0].ServiceType); - Assert.Equal(typeof(ControllerTypeA), services[0].ImplementationType); - Assert.Equal(ServiceLifetime.Transient, services[0].Lifetime); - - Assert.Equal(typeof(TypeBController), services[1].ServiceType); - Assert.Equal(typeof(TypeBController), services[1].ImplementationType); - Assert.Equal(ServiceLifetime.Transient, services[1].Lifetime); - - - Assert.Equal(typeof(IControllerActivator), services[2].ServiceType); - Assert.Equal(typeof(ServiceBasedControllerActivator), services[2].ImplementationType); - Assert.Equal(ServiceLifetime.Transient, services[2].Lifetime); - - Assert.Equal(typeof(IControllerTypeProvider), services[3].ServiceType); - var typeProvider = Assert.IsType(services[3].ImplementationInstance); - Assert.Equal(controllerTypes, typeProvider.ControllerTypes.OrderBy(c => c.Name)); - Assert.Equal(ServiceLifetime.Singleton, services[3].Lifetime); - } - // Some MVC services can be registered multiple times, for example, 'IConfigureOptions' 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. @@ -323,36 +257,5 @@ namespace Microsoft.AspNet.Mvc $"Found multiple instances of {implementationType} registered as {serviceType}"); } } - - private class CustomActivator : IControllerActivator - { - public object Create(ActionContext context, Type controllerType) - { - throw new NotImplementedException(); - } - } - - public class CustomTypeProvider : IControllerTypeProvider - { - public IEnumerable ControllerTypes { get; set; } - } - } -} - -// These controllers are used to test the UseControllersAsServices implementation -// which REQUIRES that they be public top-level classes. To avoid having to stub out the -// implementation of this class to test it, they are just top level classes. Don't reuse -// these outside this test - find a better way or use nested classes to keep the tests -// independent. -namespace Microsoft.AspNet.Mvc.MvcServiceCollectionExtensionsTestControllers -{ - public class ControllerTypeA : Controller - { - - } - - public class TypeBController - { - } } diff --git a/test/WebSites/ActionConstraintsWebSite/Startup.cs b/test/WebSites/ActionConstraintsWebSite/Startup.cs index 7c2f93b1d5..7643d152d6 100644 --- a/test/WebSites/ActionConstraintsWebSite/Startup.cs +++ b/test/WebSites/ActionConstraintsWebSite/Startup.cs @@ -12,11 +12,9 @@ namespace ActionConstraintsWebSite // Set up application services public void ConfigureServices(IServiceCollection services) { - services.AddMvc(); - services.ConfigureMvc(options => - { - options.AddXmlDataContractSerializerFormatter(); - }); + services + .AddMvc() + .AddXmlDataContractSerializerFormatters(); } public void Configure(IApplicationBuilder app) diff --git a/test/WebSites/ActionResultsWebSite/Startup.cs b/test/WebSites/ActionResultsWebSite/Startup.cs index ffbfef7d91..c96ffe05ad 100644 --- a/test/WebSites/ActionResultsWebSite/Startup.cs +++ b/test/WebSites/ActionResultsWebSite/Startup.cs @@ -12,13 +12,11 @@ namespace ActionResultsWebSite // Set up application services public void ConfigureServices(IServiceCollection services) { - services.AddMvc(); - services.AddInstance(new GuidLookupService()); + services + .AddMvc() + .AddXmlDataContractSerializerFormatters(); - services.ConfigureMvc(options => - { - options.AddXmlDataContractSerializerFormatter(); - }); + services.AddInstance(new GuidLookupService()); } public void Configure(IApplicationBuilder app) diff --git a/test/WebSites/ApiExplorerWebSite/Startup.cs b/test/WebSites/ApiExplorerWebSite/Startup.cs index 52fd2f529a..b3037e9742 100644 --- a/test/WebSites/ApiExplorerWebSite/Startup.cs +++ b/test/WebSites/ApiExplorerWebSite/Startup.cs @@ -13,10 +13,7 @@ namespace ApiExplorerWebSite // Set up application services public void ConfigureServices(IServiceCollection services) { - services.AddMvc(); - services.AddSingleton(); - - services.ConfigureMvc(options => + services.AddMvc(options => { options.Filters.AddService(typeof(ApiExplorerDataFilter)); @@ -28,6 +25,8 @@ namespace ApiExplorerWebSite options.OutputFormatters.Add(new JsonOutputFormatter()); options.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter()); }); + + services.AddSingleton(); } diff --git a/test/WebSites/ApplicationModelWebSite/Startup.cs b/test/WebSites/ApplicationModelWebSite/Startup.cs index 0bc0e9710a..5cdd6f1fe8 100644 --- a/test/WebSites/ApplicationModelWebSite/Startup.cs +++ b/test/WebSites/ApplicationModelWebSite/Startup.cs @@ -12,9 +12,7 @@ namespace ApplicationModelWebSite // Set up application services public void ConfigureServices(IServiceCollection services) { - services.AddMvc(); - - services.ConfigureMvc(options => + services.AddMvc(options => { options.Conventions.Add(new ApplicationDescription("Common Application Description")); options.Conventions.Add(new ControllerLicenseConvention()); diff --git a/test/WebSites/BasicWebSite/Startup.cs b/test/WebSites/BasicWebSite/Startup.cs index b419a981a2..f7b9d87d37 100644 --- a/test/WebSites/BasicWebSite/Startup.cs +++ b/test/WebSites/BasicWebSite/Startup.cs @@ -12,16 +12,12 @@ namespace BasicWebSite // Set up application services public void ConfigureServices(IServiceCollection services) { - // Add MVC services to the services container - services.AddMvc(); - - services.AddSingleton(); - - services.ConfigureMvc(options => + services.AddMvc(options => { options.Conventions.Add(new ApplicationDescription("This is a basic website.")); }); + services.AddSingleton(); } public void Configure(IApplicationBuilder app) diff --git a/test/WebSites/CompositeViewEngineWebSite/Startup.cs b/test/WebSites/CompositeViewEngineWebSite/Startup.cs index 5ecf695c1b..14dc7677a5 100644 --- a/test/WebSites/CompositeViewEngineWebSite/Startup.cs +++ b/test/WebSites/CompositeViewEngineWebSite/Startup.cs @@ -12,8 +12,9 @@ namespace CompositeViewEngineWebSite public void ConfigureServices(IServiceCollection services) { // Add a view engine as the first one in the list. - services.AddMvc() - .ConfigureMvcViews(options => + services + .AddMvc() + .AddViewOptions(options => { options.ViewEngines.Insert(0, new TestViewEngine()); }); diff --git a/test/WebSites/ContentNegotiationWebSite/Startup.cs b/test/WebSites/ContentNegotiationWebSite/Startup.cs index f88af07d80..10b36e90e3 100644 --- a/test/WebSites/ContentNegotiationWebSite/Startup.cs +++ b/test/WebSites/ContentNegotiationWebSite/Startup.cs @@ -12,12 +12,7 @@ namespace ContentNegotiationWebSite // Set up application services public void ConfigureServices(IServiceCollection services) { - services.AddMvc(); - - services.ConfigureMvc(options => - { - options.AddXmlDataContractSerializerFormatter(); - }); + services.AddMvc().AddXmlDataContractSerializerFormatters(); } public void Configure(IApplicationBuilder app) diff --git a/test/WebSites/ControllersFromServicesWebSite/Startup.cs b/test/WebSites/ControllersFromServicesWebSite/Startup.cs index a5af9a3f00..e9c7811eb6 100644 --- a/test/WebSites/ControllersFromServicesWebSite/Startup.cs +++ b/test/WebSites/ControllersFromServicesWebSite/Startup.cs @@ -11,15 +11,14 @@ namespace ControllersFromServicesWebSite { public class Startup { - // Set up application services public IServiceProvider ConfigureServices(IServiceCollection services) { - services.AddMvc() - .WithControllersAsServices( - new[] - { - typeof(TimeScheduleController).GetTypeInfo().Assembly - }); + services + .AddMvc() + .AddControllersAsServices(new[] + { + typeof(TimeScheduleController).GetTypeInfo().Assembly + }); services.AddTransient(); diff --git a/test/WebSites/FormatFilterWebSite/Startup.cs b/test/WebSites/FormatFilterWebSite/Startup.cs index af45536a55..c83179bf40 100644 --- a/test/WebSites/FormatFilterWebSite/Startup.cs +++ b/test/WebSites/FormatFilterWebSite/Startup.cs @@ -14,18 +14,14 @@ namespace FormatFilterWebSite // Set up application services public void ConfigureServices(IServiceCollection services) { - // Add MVC services to the services container - services.AddMvc(); - services.ConfigureMvc(options => + services.AddMvc(options => { var formatFilter = new FormatFilterAttribute(); options.Filters.Add(formatFilter); var customFormatter = new CustomFormatter("application/custom"); options.OutputFormatters.Add(customFormatter); - }); - services.ConfigureMvc(options => - { + options.FormatterMappings.SetMediaTypeMappingForFormat( "custom", MediaTypeHeaderValue.Parse("application/custom")); diff --git a/test/WebSites/FormatterWebSite/Startup.cs b/test/WebSites/FormatterWebSite/Startup.cs index f7b43fe024..1770d25289 100644 --- a/test/WebSites/FormatterWebSite/Startup.cs +++ b/test/WebSites/FormatterWebSite/Startup.cs @@ -9,28 +9,23 @@ namespace FormatterWebSite { public class Startup { - // Set up application services public void ConfigureServices(IServiceCollection services) { - // Add MVC services to the services container - services.AddMvc(); - - services.Configure(options => + services.AddMvc(options => { options.ValidationExcludeFilters.Add(typeof(Developer)); options.ValidationExcludeFilters.Add(typeof(Supplier)); - - options.AddXmlDataContractSerializerFormatter(); + options.InputFormatters.Add(new StringInputFormatter()); - }); + }) + .AddXmlDataContractSerializerFormatters(); } public void Configure(IApplicationBuilder app) { app.UseCultureReplacer(); - - // Add MVC to the request pipeline + app.UseMvc(routes => { routes.MapRoute("ActionAsMethod", "{controller}/{action}", diff --git a/test/WebSites/LocalizationWebSite/Startup.cs b/test/WebSites/LocalizationWebSite/Startup.cs index 28cbc2a11f..70fbd3666f 100644 --- a/test/WebSites/LocalizationWebSite/Startup.cs +++ b/test/WebSites/LocalizationWebSite/Startup.cs @@ -9,12 +9,9 @@ namespace LocalizationWebSite { public class Startup { - // Set up application services public void ConfigureServices(IServiceCollection services) { - // Add MVC services to the services container - services.AddMvc(); - services.AddMvcLocalization(); + services.AddMvc().AddViewLocalization(); // Adding TestStringLocalizerFactory since ResourceStringLocalizerFactory uses ResourceManager. DNX does // not support getting non-enu resources from ResourceManager yet. @@ -26,8 +23,7 @@ namespace LocalizationWebSite app.UseCultureReplacer(); app.UseRequestLocalization(); - - // Add MVC to the request pipeline + app.UseMvcWithDefaultRoute(); } } diff --git a/test/WebSites/ModelBindingWebSite/Startup.cs b/test/WebSites/ModelBindingWebSite/Startup.cs index 47ee67ff33..617ea60d42 100644 --- a/test/WebSites/ModelBindingWebSite/Startup.cs +++ b/test/WebSites/ModelBindingWebSite/Startup.cs @@ -15,18 +15,18 @@ namespace ModelBindingWebSite public void ConfigureServices(IServiceCollection services) { // Add MVC services to the services container - services.AddMvc() - .Configure(m => - { - m.MaxModelValidationErrors = 8; - m.ModelBinders.Insert(0, new TestBindingSourceModelBinder()); + services + .AddMvc(m => + { + m.MaxModelValidationErrors = 8; + m.ModelBinders.Insert(0, new TestBindingSourceModelBinder()); + + m.ValidationExcludeFilters.Add(typeof(Address)); - m.AddXmlDataContractSerializerFormatter(); - m.ValidationExcludeFilters.Add(typeof(Address)); - - // ModelMetadataController relies on additional values AdditionalValuesMetadataProvider provides. - m.ModelMetadataDetailsProviders.Add(new AdditionalValuesMetadataProvider()); - }); + // ModelMetadataController relies on additional values AdditionalValuesMetadataProvider provides. + m.ModelMetadataDetailsProviders.Add(new AdditionalValuesMetadataProvider()); + }) + .AddXmlDataContractSerializerFormatters(); services.AddSingleton(); services.AddSingleton(); diff --git a/test/WebSites/RazorWebSite/Startup.cs b/test/WebSites/RazorWebSite/Startup.cs index ddae6d73a1..d3446f2896 100644 --- a/test/WebSites/RazorWebSite/Startup.cs +++ b/test/WebSites/RazorWebSite/Startup.cs @@ -11,34 +11,33 @@ namespace RazorWebSite { public class Startup { - // Set up application services public void ConfigureServices(IServiceCollection services) { - // Add MVC services to the services container - services.AddMvc(); + services + .AddMvc() + .AddRazorOptions(options => + { + options.ViewLocationExpanders.Add(new CustomPartialDirectoryViewLocationExpander()); + }) + .AddViewOptions(options => + { + options.HtmlHelperOptions.ClientValidationEnabled = false; + options.HtmlHelperOptions.Html5DateRenderingMode = Microsoft.AspNet.Mvc.Rendering.Html5DateRenderingMode.Rfc3339; + options.HtmlHelperOptions.IdAttributeDotReplacement = "!"; + options.HtmlHelperOptions.ValidationMessageElement = "validationMessageElement"; + options.HtmlHelperOptions.ValidationSummaryMessageElement = "validationSummaryElement"; + }) + .AddViewLocalization(LanguageViewLocationExpanderFormat.SubFolder); + services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.Configure(options => - { - options.ViewLocationExpanders.Add(new CustomPartialDirectoryViewLocationExpander()); - }); - services.ConfigureMvcViews(options => - { - options.HtmlHelperOptions.ClientValidationEnabled = false; - options.HtmlHelperOptions.Html5DateRenderingMode = Microsoft.AspNet.Mvc.Rendering.Html5DateRenderingMode.Rfc3339; - options.HtmlHelperOptions.IdAttributeDotReplacement = "!"; - options.HtmlHelperOptions.ValidationMessageElement = "validationMessageElement"; - options.HtmlHelperOptions.ValidationSummaryMessageElement = "validationSummaryElement"; - }); - services.AddMvcLocalization(LanguageViewLocationExpanderFormat.SubFolder); } public void Configure(IApplicationBuilder app) { app.UseRequestLocalization(); - - // Add MVC to the request pipeline + app.UseMvcWithDefaultRoute(); } } diff --git a/test/WebSites/ResponseCacheWebSite/Startup.cs b/test/WebSites/ResponseCacheWebSite/Startup.cs index a3bf0d01c6..16c76a1300 100644 --- a/test/WebSites/ResponseCacheWebSite/Startup.cs +++ b/test/WebSites/ResponseCacheWebSite/Startup.cs @@ -9,11 +9,9 @@ namespace ResponseCacheWebSite { public class Startup { - // Set up application services public void ConfigureServices(IServiceCollection services) { - services.AddMvc(); - services.ConfigureMvc(options => + services.AddMvc(options => { options.CacheProfiles.Add( "PublicCache30Sec", new CacheProfile @@ -44,10 +42,7 @@ namespace ResponseCacheWebSite Location = ResponseCacheLocation.Any, VaryByHeader = "Accept" }); - }); - services.ConfigureMvc(options => - { options.Filters.Add(new ResponseCacheFilter(new CacheProfile { NoStore = true, diff --git a/test/WebSites/ValueProvidersWebSite/Startup.cs b/test/WebSites/ValueProvidersWebSite/Startup.cs index 3dd301876a..f06163fed8 100644 --- a/test/WebSites/ValueProvidersWebSite/Startup.cs +++ b/test/WebSites/ValueProvidersWebSite/Startup.cs @@ -11,19 +11,17 @@ namespace ValueProvidersWebSite { public void ConfigureServices(IServiceCollection services) { - // Add MVC services to the services container - services.AddMvc() - .Configure(options => - { - options.ValueProviderFactories.Insert(1, new CustomValueProviderFactory()); - }); + services + .AddMvc(options => + { + options.ValueProviderFactories.Insert(1, new CustomValueProviderFactory()); + }); } public void Configure(IApplicationBuilder app) { app.UseCultureReplacer(); - - // Add MVC to the request pipeline + app.UseMvcWithDefaultRoute(); } } diff --git a/test/WebSites/WebApiCompatShimWebSite/Startup.cs b/test/WebSites/WebApiCompatShimWebSite/Startup.cs index 33a6091201..bdaf919a07 100644 --- a/test/WebSites/WebApiCompatShimWebSite/Startup.cs +++ b/test/WebSites/WebApiCompatShimWebSite/Startup.cs @@ -12,8 +12,7 @@ namespace WebApiCompatShimWebSite public void ConfigureServices(IServiceCollection services) { // Add MVC services to the services container - services.AddMvc(); - services.AddWebApiConventions(); + services.AddMvc().AddWebApiConventions(); } public void Configure(IApplicationBuilder app)