| File: MvcServiceCollectionExtensions.cs | Web Access |
| Project: src\aspnetcore\src\Mvc\Mvc\src\Microsoft.AspNetCore.Mvc.csproj (Microsoft.AspNetCore.Mvc) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Metadata; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ApplicationParts; using Microsoft.AspNetCore.Mvc.HotReload; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Razor.TagHelpers; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.TagHelpers; using Microsoft.Extensions.DependencyInjection.Extensions; namespace Microsoft.Extensions.DependencyInjection; /// <summary> /// Extension methods for setting up MVC services in an <see cref="IServiceCollection" />. /// </summary> public static class MvcServiceCollectionExtensions { /// <summary> /// Adds MVC services to the specified <see cref="IServiceCollection" />. /// </summary> /// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param> /// <returns>An <see cref="IMvcBuilder"/> that can be used to further configure the MVC services.</returns> [RequiresUnreferencedCode("MVC does not currently support trimming or native AOT.", Url = "https://aka.ms/aspnet/trimming")] public static IMvcBuilder AddMvc(this IServiceCollection services) { ArgumentNullException.ThrowIfNull(services); services.AddControllersWithViews(); return services.AddRazorPages(); } /// <summary> /// Adds MVC services to the specified <see cref="IServiceCollection" />. /// </summary> /// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param> /// <param name="setupAction">An <see cref="Action{MvcOptions}"/> to configure the provided <see cref="MvcOptions"/>.</param> /// <returns>An <see cref="IMvcBuilder"/> that can be used to further configure the MVC services.</returns> [RequiresUnreferencedCode("MVC does not currently support trimming or native AOT.", Url = "https://aka.ms/aspnet/trimming")] public static IMvcBuilder AddMvc(this IServiceCollection services, Action<MvcOptions> setupAction) { ArgumentNullException.ThrowIfNull(services); ArgumentNullException.ThrowIfNull(setupAction); var builder = services.AddMvc(); builder.Services.Configure(setupAction); return builder; } /// <summary> /// Adds services for controllers to the specified <see cref="IServiceCollection"/>. This method will not /// register services used for views or pages. /// </summary> /// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param> /// <returns>An <see cref="IMvcBuilder"/> that can be used to further configure the MVC services.</returns> /// <remarks> /// <para> /// This method configures the MVC services for the commonly used features with controllers for an API. This /// combines the effects of <see cref="MvcCoreServiceCollectionExtensions.AddMvcCore(IServiceCollection)"/>, /// <see cref="MvcApiExplorerMvcCoreBuilderExtensions.AddApiExplorer(IMvcCoreBuilder)"/>, /// <see cref="MvcCoreMvcCoreBuilderExtensions.AddAuthorization(IMvcCoreBuilder)"/>, /// <see cref="MvcCorsMvcCoreBuilderExtensions.AddCors(IMvcCoreBuilder)"/>, /// <see cref="MvcDataAnnotationsMvcCoreBuilderExtensions.AddDataAnnotations(IMvcCoreBuilder)"/>, /// and <see cref="MvcCoreMvcCoreBuilderExtensions.AddFormatterMappings(IMvcCoreBuilder)"/>. /// </para> /// <para> /// To add services for controllers with views call <see cref="AddControllersWithViews(IServiceCollection)"/> /// on the resulting builder. /// </para> /// <para> /// To add services for pages call <see cref="AddRazorPages(IServiceCollection)"/> /// on the resulting builder. /// </para> /// </remarks> [RequiresUnreferencedCode("MVC does not currently support trimming or native AOT.", Url = "https://aka.ms/aspnet/trimming")] public static IMvcBuilder AddControllers(this IServiceCollection services) { ArgumentNullException.ThrowIfNull(services); var builder = AddControllersCore(services); return new MvcBuilder(builder.Services, builder.PartManager); } /// <summary> /// Adds services for controllers to the specified <see cref="IServiceCollection"/>. This method will not /// register services used for views or pages. /// </summary> /// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param> /// <param name="configure">An <see cref="Action{MvcOptions}"/> to configure the provided <see cref="MvcOptions"/>.</param> /// <returns>An <see cref="IMvcBuilder"/> that can be used to further configure the MVC services.</returns> /// <remarks> /// <para> /// This method configures the MVC services for the commonly used features with controllers for an API. This /// combines the effects of <see cref="MvcCoreServiceCollectionExtensions.AddMvcCore(IServiceCollection)"/>, /// <see cref="MvcApiExplorerMvcCoreBuilderExtensions.AddApiExplorer(IMvcCoreBuilder)"/>, /// <see cref="MvcCoreMvcCoreBuilderExtensions.AddAuthorization(IMvcCoreBuilder)"/>, /// <see cref="MvcCorsMvcCoreBuilderExtensions.AddCors(IMvcCoreBuilder)"/>, /// <see cref="MvcDataAnnotationsMvcCoreBuilderExtensions.AddDataAnnotations(IMvcCoreBuilder)"/>, /// and <see cref="MvcCoreMvcCoreBuilderExtensions.AddFormatterMappings(IMvcCoreBuilder)"/>. /// </para> /// <para> /// To add services for controllers with views call <see cref="AddControllersWithViews(IServiceCollection)"/> /// on the resulting builder. /// </para> /// <para> /// To add services for pages call <see cref="AddRazorPages(IServiceCollection)"/> /// on the resulting builder. /// </para> /// </remarks> [RequiresUnreferencedCode("MVC does not currently support trimming or native AOT.", Url = "https://aka.ms/aspnet/trimming")] public static IMvcBuilder AddControllers(this IServiceCollection services, Action<MvcOptions>? configure) { ArgumentNullException.ThrowIfNull(services); // This method excludes all of the view-related services by default. var builder = AddControllersCore(services); if (configure != null) { builder.AddMvcOptions(configure); } return new MvcBuilder(builder.Services, builder.PartManager); } private static IMvcCoreBuilder AddControllersCore(IServiceCollection services) { // This method excludes all of the view-related services by default. var builder = services .AddMvcCore() .AddApiExplorer() .AddAuthorization() .AddCors() .AddDataAnnotations() .AddFormatterMappings(); if (MetadataUpdater.IsSupported) { services.TryAddEnumerable( ServiceDescriptor.Singleton<IActionDescriptorChangeProvider, HotReloadService>()); } return builder; } /// <summary> /// Adds services for controllers to the specified <see cref="IServiceCollection"/>. This method will not /// register services used for pages. /// </summary> /// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param> /// <returns>An <see cref="IMvcBuilder"/> that can be used to further configure the MVC services.</returns> /// <remarks> /// <para> /// This method configures the MVC services for the commonly used features with controllers with views. This /// combines the effects of <see cref="MvcCoreServiceCollectionExtensions.AddMvcCore(IServiceCollection)"/>, /// <see cref="MvcApiExplorerMvcCoreBuilderExtensions.AddApiExplorer(IMvcCoreBuilder)"/>, /// <see cref="MvcCoreMvcCoreBuilderExtensions.AddAuthorization(IMvcCoreBuilder)"/>, /// <see cref="MvcCorsMvcCoreBuilderExtensions.AddCors(IMvcCoreBuilder)"/>, /// <see cref="MvcDataAnnotationsMvcCoreBuilderExtensions.AddDataAnnotations(IMvcCoreBuilder)"/>, /// <see cref="MvcCoreMvcCoreBuilderExtensions.AddFormatterMappings(IMvcCoreBuilder)"/>, /// <see cref="TagHelperServicesExtensions.AddCacheTagHelper(IMvcCoreBuilder)"/>, /// <see cref="MvcViewFeaturesMvcCoreBuilderExtensions.AddViews(IMvcCoreBuilder)"/>, /// and <see cref="MvcRazorMvcCoreBuilderExtensions.AddRazorViewEngine(IMvcCoreBuilder)"/>. /// </para> /// <para> /// To add services for pages call <see cref="AddRazorPages(IServiceCollection)"/>. /// </para> /// </remarks> [RequiresUnreferencedCode("MVC does not currently support trimming or native AOT.", Url = "https://aka.ms/aspnet/trimming")] public static IMvcBuilder AddControllersWithViews(this IServiceCollection services) { ArgumentNullException.ThrowIfNull(services); var builder = AddControllersWithViewsCore(services); return new MvcBuilder(builder.Services, builder.PartManager); } /// <summary> /// Adds services for controllers to the specified <see cref="IServiceCollection"/>. This method will not /// register services used for pages. /// </summary> /// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param> /// <param name="configure">An <see cref="Action{MvcOptions}"/> to configure the provided <see cref="MvcOptions"/>.</param> /// <returns>An <see cref="IMvcBuilder"/> that can be used to further configure the MVC services.</returns> /// <remarks> /// <para> /// This method configures the MVC services for the commonly used features with controllers with views. This /// combines the effects of <see cref="MvcCoreServiceCollectionExtensions.AddMvcCore(IServiceCollection)"/>, /// <see cref="MvcApiExplorerMvcCoreBuilderExtensions.AddApiExplorer(IMvcCoreBuilder)"/>, /// <see cref="MvcCoreMvcCoreBuilderExtensions.AddAuthorization(IMvcCoreBuilder)"/>, /// <see cref="MvcCorsMvcCoreBuilderExtensions.AddCors(IMvcCoreBuilder)"/>, /// <see cref="MvcDataAnnotationsMvcCoreBuilderExtensions.AddDataAnnotations(IMvcCoreBuilder)"/>, /// <see cref="MvcCoreMvcCoreBuilderExtensions.AddFormatterMappings(IMvcCoreBuilder)"/>, /// <see cref="TagHelperServicesExtensions.AddCacheTagHelper(IMvcCoreBuilder)"/>, /// <see cref="MvcViewFeaturesMvcCoreBuilderExtensions.AddViews(IMvcCoreBuilder)"/>, /// and <see cref="MvcRazorMvcCoreBuilderExtensions.AddRazorViewEngine(IMvcCoreBuilder)"/>. /// </para> /// <para> /// To add services for pages call <see cref="AddRazorPages(IServiceCollection)"/>. /// </para> /// </remarks> [RequiresUnreferencedCode("MVC does not currently support trimming or native AOT.", Url = "https://aka.ms/aspnet/trimming")] public static IMvcBuilder AddControllersWithViews(this IServiceCollection services, Action<MvcOptions>? configure) { ArgumentNullException.ThrowIfNull(services); // This method excludes all of the view-related services by default. var builder = AddControllersWithViewsCore(services); if (configure != null) { builder.AddMvcOptions(configure); } return new MvcBuilder(builder.Services, builder.PartManager); } private static IMvcCoreBuilder AddControllersWithViewsCore(IServiceCollection services) { var builder = AddControllersCore(services) .AddViews() .AddRazorViewEngine() .AddCacheTagHelper(); AddTagHelpersFrameworkParts(builder.PartManager); return builder; } /// <summary> /// Adds services for pages to the specified <see cref="IServiceCollection"/>. /// </summary> /// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param> /// <returns>An <see cref="IMvcBuilder"/> that can be used to further configure the MVC services.</returns> /// <remarks> /// <para> /// This method configures the MVC services for the commonly used features for pages. This /// combines the effects of <see cref="MvcCoreServiceCollectionExtensions.AddMvcCore(IServiceCollection)"/>, /// <see cref="MvcCoreMvcCoreBuilderExtensions.AddAuthorization(IMvcCoreBuilder)"/>, /// <see cref="MvcDataAnnotationsMvcCoreBuilderExtensions.AddDataAnnotations(IMvcCoreBuilder)"/>, /// <see cref="TagHelperServicesExtensions.AddCacheTagHelper(IMvcCoreBuilder)"/>, /// and <see cref="MvcRazorPagesMvcCoreBuilderExtensions.AddRazorPages(IMvcCoreBuilder)"/>. /// </para> /// <para> /// To add services for controllers for APIs call <see cref="AddControllers(IServiceCollection)"/>. /// </para> /// <para> /// To add services for controllers with views call <see cref="AddControllersWithViews(IServiceCollection)"/>. /// </para> /// </remarks> [RequiresUnreferencedCode("Razor Pages does not currently support trimming or native AOT.", Url = "https://aka.ms/aspnet/trimming")] public static IMvcBuilder AddRazorPages(this IServiceCollection services) { ArgumentNullException.ThrowIfNull(services); var builder = AddRazorPagesCore(services); return new MvcBuilder(builder.Services, builder.PartManager); } /// <summary> /// Adds services for pages to the specified <see cref="IServiceCollection"/>. /// </summary> /// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param> /// <param name="configure">An <see cref="Action{MvcOptions}"/> to configure the provided <see cref="MvcOptions"/>.</param> /// <returns>An <see cref="IMvcBuilder"/> that can be used to further configure the MVC services.</returns> /// <remarks> /// <para> /// This method configures the MVC services for the commonly used features for pages. This /// combines the effects of <see cref="MvcCoreServiceCollectionExtensions.AddMvcCore(IServiceCollection)"/>, /// <see cref="MvcCoreMvcCoreBuilderExtensions.AddAuthorization(IMvcCoreBuilder)"/>, /// <see cref="MvcDataAnnotationsMvcCoreBuilderExtensions.AddDataAnnotations(IMvcCoreBuilder)"/>, /// <see cref="TagHelperServicesExtensions.AddCacheTagHelper(IMvcCoreBuilder)"/>, /// and <see cref="MvcRazorPagesMvcCoreBuilderExtensions.AddRazorPages(IMvcCoreBuilder)"/>. /// </para> /// <para> /// To add services for controllers for APIs call <see cref="AddControllers(IServiceCollection)"/>. /// </para> /// <para> /// To add services for controllers with views call <see cref="AddControllersWithViews(IServiceCollection)"/>. /// </para> /// </remarks> [RequiresUnreferencedCode("Razor Pages does not currently support trimming or native AOT.", Url = "https://aka.ms/aspnet/trimming")] public static IMvcBuilder AddRazorPages(this IServiceCollection services, Action<RazorPagesOptions>? configure) { ArgumentNullException.ThrowIfNull(services); var builder = AddRazorPagesCore(services); if (configure != null) { builder.AddRazorPages(configure); } return new MvcBuilder(builder.Services, builder.PartManager); } private static IMvcCoreBuilder AddRazorPagesCore(IServiceCollection services) { // This method includes the minimal things controllers need. It's not really feasible to exclude the services // for controllers. var builder = services .AddMvcCore() .AddAuthorization() .AddDataAnnotations() .AddRazorPages() .AddCacheTagHelper(); AddTagHelpersFrameworkParts(builder.PartManager); if (MetadataUpdater.IsSupported) { services.TryAddEnumerable( ServiceDescriptor.Singleton<IActionDescriptorChangeProvider, HotReloadService>()); } return builder; } internal static void AddTagHelpersFrameworkParts(ApplicationPartManager partManager) { var mvcTagHelpersAssembly = typeof(InputTagHelper).Assembly; if (!partManager.ApplicationParts.OfType<AssemblyPart>().Any(p => p.Assembly == mvcTagHelpersAssembly)) { partManager.ApplicationParts.Add(new FrameworkAssemblyPart(mvcTagHelpersAssembly)); } var mvcRazorAssembly = typeof(UrlResolutionTagHelper).Assembly; if (!partManager.ApplicationParts.OfType<AssemblyPart>().Any(p => p.Assembly == mvcRazorAssembly)) { partManager.ApplicationParts.Add(new FrameworkAssemblyPart(mvcRazorAssembly)); } } [DebuggerDisplay("{Name}")] private sealed class FrameworkAssemblyPart : AssemblyPart, ICompilationReferencesProvider { public FrameworkAssemblyPart(Assembly assembly) : base(assembly) { } IEnumerable<string> ICompilationReferencesProvider.GetReferencePaths() => Enumerable.Empty<string>(); } }