From 5d72a7f7479d7e26bad9a1e9574004545543028c Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 24 May 2016 17:39:27 -0700 Subject: [PATCH] Modify ICompilationLibrariesProvider to return a sequence of reference path Fixes #4738 --- .../ApplicationParts/AssemblyPart.cs | 13 +++++--- ...r.cs => ICompilationReferencesProvider.cs} | 9 +++--- .../MetadataReferenceFeatureProvider.cs | 18 ++++------- .../ApplicationParts/AssemblyPartTest.cs | 32 +++++++++++++++++++ .../MetadataReferenceFeatureProviderTest.cs | 17 ---------- 5 files changed, 51 insertions(+), 38 deletions(-) rename src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/{ICompilationLibrariesProvider.cs => ICompilationReferencesProvider.cs} (51%) diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/AssemblyPart.cs b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/AssemblyPart.cs index 12d251c725..6426753d4b 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/AssemblyPart.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/AssemblyPart.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using Microsoft.Extensions.DependencyModel; @@ -11,7 +12,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts /// /// An backed by an . /// - public class AssemblyPart : ApplicationPart, IApplicationPartTypeProvider, ICompilationLibrariesProvider + public class AssemblyPart : ApplicationPart, IApplicationPartTypeProvider, ICompilationReferencesProvider { /// /// Initalizes a new instance. @@ -41,15 +42,19 @@ public AssemblyPart(Assembly assembly) public IEnumerable Types => Assembly.DefinedTypes; /// - public IReadOnlyList GetCompilationLibraries() + public IEnumerable GetReferencePaths() { var dependencyContext = DependencyContext.Load(Assembly); if (dependencyContext != null) { - return dependencyContext.CompileLibraries; + return dependencyContext.CompileLibraries.SelectMany(library => library.ResolveReferencePaths()); } - return new CompilationLibrary[0]; + // If an application has been compiled without preserveCompilationContext, return the path to the assembly + // as a reference. For runtime compilation, this will allow the compilation to succeed as long as it least + // one application part has been compiled with preserveCompilationContext and contains a super set of types + // required for the compilation to succeed. + return new[] { Assembly.Location }; } } } diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ICompilationLibrariesProvider.cs b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ICompilationReferencesProvider.cs similarity index 51% rename from src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ICompilationLibrariesProvider.cs rename to src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ICompilationReferencesProvider.cs index 81b28544b2..bb2691bedd 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ICompilationLibrariesProvider.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ICompilationReferencesProvider.cs @@ -2,18 +2,17 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using Microsoft.Extensions.DependencyModel; namespace Microsoft.AspNetCore.Mvc.ApplicationParts { /// - /// Exposes instances from an . + /// Exposes one or more reference paths from an . /// - public interface ICompilationLibrariesProvider + public interface ICompilationReferencesProvider { /// - /// Gets the sequence of instances. + /// Gets reference paths used to perform runtime compilation. /// - IReadOnlyList GetCompilationLibraries(); + IEnumerable GetReferencePaths(); } } diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/Compilation/MetadataReferenceFeatureProvider.cs b/src/Microsoft.AspNetCore.Mvc.Razor/Compilation/MetadataReferenceFeatureProvider.cs index 2651e209fc..f5a42ace01 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor/Compilation/MetadataReferenceFeatureProvider.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor/Compilation/MetadataReferenceFeatureProvider.cs @@ -33,21 +33,15 @@ public void PopulateFeature(IEnumerable parts, MetadataReferenc } var libraryPaths = new HashSet(StringComparer.OrdinalIgnoreCase); - foreach (var providerPart in parts.OfType()) + foreach (var providerPart in parts.OfType()) { - var compileLibraries = providerPart.GetCompilationLibraries(); - - for (var i = 0; i < compileLibraries.Count; i++) + var referencePaths = providerPart.GetReferencePaths(); + foreach (var path in referencePaths) { - var library = compileLibraries[i]; - var referencePaths = library.ResolveReferencePaths(); - foreach (var path in referencePaths) + if (libraryPaths.Add(path)) { - if (libraryPaths.Add(path)) - { - var metadataReference = CreateMetadataReference(path); - feature.MetadataReferences.Add(metadataReference); - } + var metadataReference = CreateMetadataReference(path); + feature.MetadataReferences.Add(metadataReference); } } } diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationParts/AssemblyPartTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationParts/AssemblyPartTest.cs index dea3859282..39fc99a573 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationParts/AssemblyPartTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ApplicationParts/AssemblyPartTest.cs @@ -1,6 +1,7 @@ // 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 Xunit; @@ -46,5 +47,36 @@ public void AssemblyPart_Assembly_ReturnsAssembly() // Act & Assert Assert.Equal(part.Assembly, assembly); } + + [Fact] + public void GetReferencePaths_ReturnsReferencesFromDependencyContext_IfPreserveCompilationContextIsSet() + { + // Arrange + var assembly = GetType().GetTypeInfo().Assembly; + var part = new AssemblyPart(assembly); + + // Act + var references = part.GetReferencePaths().ToList(); + + // Assert + Assert.Contains(assembly.Location, references); + Assert.Contains(typeof(AssemblyPart).GetTypeInfo().Assembly.Location, references); + } + + [Fact] + public void GetReferencePaths_ReturnsAssebmlyLocation_IfPreserveCompilationContextIsNotSet() + { + // Arrange + // src projects do not have preserveCompilationContext specified. + var assembly = typeof(AssemblyPart).GetTypeInfo().Assembly; + var part = new AssemblyPart(assembly); + + // Act + var references = part.GetReferencePaths().ToList(); + + // Assert + var actual = Assert.Single(references); + Assert.Equal(assembly.Location, actual); + } } } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Test/Compilation/MetadataReferenceFeatureProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Test/Compilation/MetadataReferenceFeatureProviderTest.cs index 6ae0f9d964..fe05fdb561 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Test/Compilation/MetadataReferenceFeatureProviderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Test/Compilation/MetadataReferenceFeatureProviderTest.cs @@ -26,23 +26,6 @@ public void PopulateFeature_ReturnsEmptyList_IfNoAssemblyPartsAreRegistered() Assert.Empty(feature.MetadataReferences); } - [Fact] - public void PopulateFeature_ReturnsEmptySequence_IfAssemblyDoesNotPreserveCompilationContext() - { - // Arrange - var applicationPartManager = new ApplicationPartManager(); - var assemblyPart = new AssemblyPart(typeof(MetadataReferenceFeatureProvider).GetTypeInfo().Assembly); - applicationPartManager.ApplicationParts.Add(assemblyPart); - applicationPartManager.FeatureProviders.Add(new MetadataReferenceFeatureProvider()); - var feature = new MetadataReferenceFeature(); - - // Act - applicationPartManager.PopulateFeature(feature); - - // Assert - Assert.Empty(feature.MetadataReferences); - } - [Fact] public void PopulateFeature_AddsMetadataReferenceForAssemblyPartsWithDependencyContext() {