Do not throw if a library does not have a runtime component

Fixes #5690
This commit is contained in:
Pranav K 2017-03-14 09:48:26 -07:00
parent 6d62423e6a
commit de25357c28
2 changed files with 57 additions and 15 deletions

View File

@ -3,7 +3,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Microsoft.AspNetCore.Mvc.ApplicationParts; using Microsoft.AspNetCore.Mvc.ApplicationParts;
@ -71,12 +70,12 @@ namespace Microsoft.AspNetCore.Mvc.Internal
private class CandidateResolver private class CandidateResolver
{ {
private readonly IDictionary<string, Dependency> _dependencies; private readonly IDictionary<string, Dependency> _runtimeDependencies;
public CandidateResolver(IReadOnlyList<RuntimeLibrary> dependencies, ISet<string> referenceAssemblies) public CandidateResolver(IReadOnlyList<RuntimeLibrary> runtimeDependencies, ISet<string> referenceAssemblies)
{ {
var dependenciesWithNoDuplicates = new Dictionary<string, Dependency>(StringComparer.OrdinalIgnoreCase); var dependenciesWithNoDuplicates = new Dictionary<string, Dependency>(StringComparer.OrdinalIgnoreCase);
foreach (var dependency in dependencies) foreach (var dependency in runtimeDependencies)
{ {
if (dependenciesWithNoDuplicates.ContainsKey(dependency.Name)) if (dependenciesWithNoDuplicates.ContainsKey(dependency.Name))
{ {
@ -85,7 +84,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
dependenciesWithNoDuplicates.Add(dependency.Name, CreateDependency(dependency, referenceAssemblies)); dependenciesWithNoDuplicates.Add(dependency.Name, CreateDependency(dependency, referenceAssemblies));
} }
_dependencies = dependenciesWithNoDuplicates; _runtimeDependencies = dependenciesWithNoDuplicates;
} }
private Dependency CreateDependency(RuntimeLibrary library, ISet<string> referenceAssemblies) private Dependency CreateDependency(RuntimeLibrary library, ISet<string> referenceAssemblies)
@ -101,23 +100,28 @@ namespace Microsoft.AspNetCore.Mvc.Internal
private DependencyClassification ComputeClassification(string dependency) private DependencyClassification ComputeClassification(string dependency)
{ {
Debug.Assert(_dependencies.ContainsKey(dependency)); if (!_runtimeDependencies.ContainsKey(dependency))
{
// Library does not have runtime dependency. Since we can't infer
// anything about it's references, we'll assume it does not have a reference to Mvc.
return DependencyClassification.DoesNotReferenceMvc;
}
var candidateEntry = _dependencies[dependency]; var candidateEntry = _runtimeDependencies[dependency];
if (candidateEntry.Classification != DependencyClassification.Unknown) if (candidateEntry.Classification != DependencyClassification.Unknown)
{ {
return candidateEntry.Classification; return candidateEntry.Classification;
} }
else else
{ {
var classification = DependencyClassification.NotCandidate; var classification = DependencyClassification.DoesNotReferenceMvc;
foreach (var candidateDependency in candidateEntry.Library.Dependencies) foreach (var candidateDependency in candidateEntry.Library.Dependencies)
{ {
var dependencyClassification = ComputeClassification(candidateDependency.Name); var dependencyClassification = ComputeClassification(candidateDependency.Name);
if (dependencyClassification == DependencyClassification.Candidate || if (dependencyClassification == DependencyClassification.ReferencesMvc ||
dependencyClassification == DependencyClassification.MvcReference) dependencyClassification == DependencyClassification.MvcReference)
{ {
classification = DependencyClassification.Candidate; classification = DependencyClassification.ReferencesMvc;
break; break;
} }
} }
@ -130,9 +134,9 @@ namespace Microsoft.AspNetCore.Mvc.Internal
public IEnumerable<RuntimeLibrary> GetCandidates() public IEnumerable<RuntimeLibrary> GetCandidates()
{ {
foreach (var dependency in _dependencies) foreach (var dependency in _runtimeDependencies)
{ {
if (ComputeClassification(dependency.Key) == DependencyClassification.Candidate) if (ComputeClassification(dependency.Key) == DependencyClassification.ReferencesMvc)
{ {
yield return dependency.Value.Library; yield return dependency.Value.Library;
} }
@ -160,9 +164,23 @@ namespace Microsoft.AspNetCore.Mvc.Internal
private enum DependencyClassification private enum DependencyClassification
{ {
Unknown = 0, Unknown = 0,
Candidate = 1,
NotCandidate = 2, /// <summary>
MvcReference = 3 /// References (directly or transitively) one of the Mvc packages listed in
/// <see cref="ReferenceAssemblies"/>.
/// </summary>
ReferencesMvc = 1,
/// <summary>
/// Does not reference (directly or transitively) one of the Mvc packages listed by
/// <see cref="ReferenceAssemblies"/>.
/// </summary>
DoesNotReferenceMvc = 2,
/// <summary>
/// One of the references listed in <see cref="ReferenceAssemblies"/>.
/// </summary>
MvcReference = 3,
} }
} }
} }

View File

@ -64,6 +64,30 @@ namespace Microsoft.AspNetCore.Mvc.Internal
Assert.Equal(new[] { expected }, candidates); Assert.Equal(new[] { expected }, candidates);
} }
[Fact]
public void GetCandidateLibraries_DoesNotThrow_IfLibraryDoesNotHaveRuntimeComponent()
{
// Arrange
var expected = GetLibrary("MyApplication", "Microsoft.AspNetCore.Server.Kestrel", "Microsoft.AspNetCore.Mvc");
var deps = new DependencyContext(
new TargetInfo("netcoreapp1.1", "rurntime", "signature", isPortable: true),
CompilationOptions.Default,
Enumerable.Empty<CompilationLibrary>(),
new[]
{
expected,
GetLibrary("Microsoft.AspNetCore.Server.Kestrel", "Libuv"),
GetLibrary("Microsoft.AspNetCore.Mvc"),
},
Enumerable.Empty<RuntimeFallbacks>());
// Act
var candidates = DefaultAssemblyPartDiscoveryProvider.GetCandidateLibraries(deps).ToList();
// Assert
Assert.Equal(new[] { expected }, candidates);
}
[Fact] [Fact]
public void CandidateAssemblies_ReturnsEntryAssemblyIfDependencyContextIsNull() public void CandidateAssemblies_ReturnsEntryAssemblyIfDependencyContextIsNull()
{ {