diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs b/src/Microsoft.AspNetCore.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs index 423f00275b..f4a89f9587 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs @@ -67,6 +67,11 @@ namespace Microsoft.Extensions.DependencyInjection builder.PartManager.FeatureProviders.Add(new MetadataReferenceFeatureProvider()); } + if (!builder.PartManager.FeatureProviders.OfType().Any()) + { + builder.PartManager.FeatureProviders.Add(new TagHelperFeatureProvider()); + } + if (!builder.PartManager.FeatureProviders.OfType().Any()) { builder.PartManager.FeatureProviders.Add(new ViewsFeatureProvider()); diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/TagHelpers/TagHelperFeatureProvider.cs b/src/Microsoft.AspNetCore.Mvc.Razor/TagHelpers/TagHelperFeatureProvider.cs new file mode 100644 index 0000000000..40e2e58a10 --- /dev/null +++ b/src/Microsoft.AspNetCore.Mvc.Razor/TagHelpers/TagHelperFeatureProvider.cs @@ -0,0 +1,43 @@ +// 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.Collections.Generic; +using System.Linq; +using System.Reflection; +using Microsoft.AspNetCore.Mvc.ApplicationParts; +using Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers +{ + public class TagHelperFeatureProvider : IApplicationFeatureProvider + { + public void PopulateFeature(IEnumerable parts, TagHelperFeature feature) + { + foreach (var part in parts) + { + if (IncludePart(part) && part is IApplicationPartTypeProvider typeProvider) + { + foreach (var type in typeProvider.Types) + { + var typeInfo = type.GetTypeInfo(); + if (IncludeType(typeInfo) && !feature.TagHelpers.Contains(typeInfo)) + { + feature.TagHelpers.Add(typeInfo); + } + } + } + } + } + + protected virtual bool IncludePart(ApplicationPart part) => true; + + protected virtual bool IncludeType(TypeInfo type) + { + // We don't need to check visibility here, that's handled by the type provider. + return + typeof(ITagHelper).GetTypeInfo().IsAssignableFrom(type) && + !type.IsAbstract && + !type.IsGenericType; + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/TagHelpersFromServicesTest.cs b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/TagHelpersFromServicesTest.cs index aa33cade3c..2f083e06df 100644 --- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/TagHelpersFromServicesTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/TagHelpersFromServicesTest.cs @@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests public HttpClient Client { get; } - [Fact(Skip = "Workaround for https://github.com/aspnet/Mvc/issues/5768.")] + [Fact] public async Task TagHelpersWithConstructorInjectionAreCreatedAndActivated() { // Arrange diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Test/DependencyInjection/MvcRazorMvcBuilderExtensionsTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Test/DependencyInjection/MvcRazorMvcBuilderExtensionsTest.cs index ef93c6eb6f..eecee7664c 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Test/DependencyInjection/MvcRazorMvcBuilderExtensionsTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Test/DependencyInjection/MvcRazorMvcBuilderExtensionsTest.cs @@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Test.DependencyInjection typeof(TestTagHelperOne), typeof(TestTagHelperTwo))); - manager.FeatureProviders.Add(new TestFeatureProvider()); + manager.FeatureProviders.Add(new TagHelperFeatureProvider()); var builder = new MvcBuilder(services, manager); @@ -78,16 +78,5 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Test.DependencyInjection private class TestTagHelperTwo : TagHelper { } - - private class TestFeatureProvider : IApplicationFeatureProvider - { - public void PopulateFeature(IEnumerable parts, TagHelperFeature feature) - { - foreach (var type in parts.OfType().SelectMany(tp => tp.Types)) - { - feature.TagHelpers.Add(type); - } - } - } } } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Test/DependencyInjection/MvcRazorMvcCoreBuilderExtensionsTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Test/DependencyInjection/MvcRazorMvcCoreBuilderExtensionsTest.cs index 2db533554f..6ea2e2afb5 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Test/DependencyInjection/MvcRazorMvcCoreBuilderExtensionsTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Test/DependencyInjection/MvcRazorMvcCoreBuilderExtensionsTest.cs @@ -9,7 +9,6 @@ using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.Razor.Compilation; using Microsoft.AspNetCore.Mvc.Razor.Internal; using Microsoft.AspNetCore.Mvc.Razor.TagHelpers; -using Microsoft.AspNetCore.Razor.Runtime.TagHelpers; using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.Extensions.DependencyInjection; using Moq; diff --git a/test/Microsoft.AspNetCore.Mvc.Test/MvcServiceCollectionExtensionsTest.cs b/test/Microsoft.AspNetCore.Mvc.Test/MvcServiceCollectionExtensionsTest.cs index 4e6fbeb7fb..3174f5d8d9 100644 --- a/test/Microsoft.AspNetCore.Mvc.Test/MvcServiceCollectionExtensionsTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Test/MvcServiceCollectionExtensionsTest.cs @@ -214,6 +214,7 @@ namespace Microsoft.AspNetCore.Mvc feature => Assert.IsType(feature), feature => Assert.IsType(feature), feature => Assert.IsType(feature), + feature => Assert.IsType(feature), feature => Assert.IsType(feature), feature => Assert.IsType(feature)); }