Modify ICompilationLibrariesProvider to return a sequence of reference path

Fixes #4738
This commit is contained in:
Pranav K 2016-05-24 17:39:27 -07:00
parent 9acd0f578c
commit 5d72a7f747
5 changed files with 51 additions and 38 deletions

View File

@ -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
/// <summary>
/// An <see cref="ApplicationPart"/> backed by an <see cref="Assembly"/>.
/// </summary>
public class AssemblyPart : ApplicationPart, IApplicationPartTypeProvider, ICompilationLibrariesProvider
public class AssemblyPart : ApplicationPart, IApplicationPartTypeProvider, ICompilationReferencesProvider
{
/// <summary>
/// Initalizes a new <see cref="AssemblyPart"/> instance.
@ -41,15 +42,19 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts
public IEnumerable<TypeInfo> Types => Assembly.DefinedTypes;
/// <inheritdoc />
public IReadOnlyList<CompilationLibrary> GetCompilationLibraries()
public IEnumerable<string> 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 };
}
}
}

View File

@ -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
{
/// <summary>
/// Exposes <see cref="CompilationLibrary"/> instances from an <see cref="ApplicationPart"/>.
/// Exposes one or more reference paths from an <see cref="ApplicationPart"/>.
/// </summary>
public interface ICompilationLibrariesProvider
public interface ICompilationReferencesProvider
{
/// <summary>
/// Gets the sequence of <see cref="CompilationLibrary"/> instances.
/// Gets reference paths used to perform runtime compilation.
/// </summary>
IReadOnlyList<CompilationLibrary> GetCompilationLibraries();
IEnumerable<string> GetReferencePaths();
}
}

View File

@ -33,21 +33,15 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Compilation
}
var libraryPaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var providerPart in parts.OfType<ICompilationLibrariesProvider>())
foreach (var providerPart in parts.OfType<ICompilationReferencesProvider>())
{
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);
}
}
}

View File

@ -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 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts
// 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);
}
}
}

View File

@ -26,23 +26,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Compilation
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()
{