diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/DefaultAssemblyPartDiscoveryProvider.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/DefaultAssemblyPartDiscoveryProvider.cs index c0412bf707..f006a4d360 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/DefaultAssemblyPartDiscoveryProvider.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/DefaultAssemblyPartDiscoveryProvider.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Reflection; using Microsoft.AspNetCore.Mvc.ApplicationParts; @@ -71,12 +70,12 @@ namespace Microsoft.AspNetCore.Mvc.Internal private class CandidateResolver { - private readonly IDictionary _dependencies; + private readonly IDictionary _runtimeDependencies; - public CandidateResolver(IReadOnlyList dependencies, ISet referenceAssemblies) + public CandidateResolver(IReadOnlyList runtimeDependencies, ISet referenceAssemblies) { var dependenciesWithNoDuplicates = new Dictionary(StringComparer.OrdinalIgnoreCase); - foreach (var dependency in dependencies) + foreach (var dependency in runtimeDependencies) { if (dependenciesWithNoDuplicates.ContainsKey(dependency.Name)) { @@ -85,7 +84,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal dependenciesWithNoDuplicates.Add(dependency.Name, CreateDependency(dependency, referenceAssemblies)); } - _dependencies = dependenciesWithNoDuplicates; + _runtimeDependencies = dependenciesWithNoDuplicates; } private Dependency CreateDependency(RuntimeLibrary library, ISet referenceAssemblies) @@ -101,23 +100,28 @@ namespace Microsoft.AspNetCore.Mvc.Internal 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) { return candidateEntry.Classification; } else { - var classification = DependencyClassification.NotCandidate; + var classification = DependencyClassification.DoesNotReferenceMvc; foreach (var candidateDependency in candidateEntry.Library.Dependencies) { var dependencyClassification = ComputeClassification(candidateDependency.Name); - if (dependencyClassification == DependencyClassification.Candidate || + if (dependencyClassification == DependencyClassification.ReferencesMvc || dependencyClassification == DependencyClassification.MvcReference) { - classification = DependencyClassification.Candidate; + classification = DependencyClassification.ReferencesMvc; break; } } @@ -130,9 +134,9 @@ namespace Microsoft.AspNetCore.Mvc.Internal public IEnumerable 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; } @@ -160,9 +164,23 @@ namespace Microsoft.AspNetCore.Mvc.Internal private enum DependencyClassification { Unknown = 0, - Candidate = 1, - NotCandidate = 2, - MvcReference = 3 + + /// + /// References (directly or transitively) one of the Mvc packages listed in + /// . + /// + ReferencesMvc = 1, + + /// + /// Does not reference (directly or transitively) one of the Mvc packages listed by + /// . + /// + DoesNotReferenceMvc = 2, + + /// + /// One of the references listed in . + /// + MvcReference = 3, } } } diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/DefaultAssemblyPartDiscoveryProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/DefaultAssemblyPartDiscoveryProviderTest.cs index b457d3a686..fadf55ab2d 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/DefaultAssemblyPartDiscoveryProviderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/DefaultAssemblyPartDiscoveryProviderTest.cs @@ -64,6 +64,30 @@ namespace Microsoft.AspNetCore.Mvc.Internal 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(), + new[] + { + expected, + GetLibrary("Microsoft.AspNetCore.Server.Kestrel", "Libuv"), + GetLibrary("Microsoft.AspNetCore.Mvc"), + }, + Enumerable.Empty()); + + // Act + var candidates = DefaultAssemblyPartDiscoveryProvider.GetCandidateLibraries(deps).ToList(); + + // Assert + Assert.Equal(new[] { expected }, candidates); + } + [Fact] public void CandidateAssemblies_ReturnsEntryAssemblyIfDependencyContextIsNull() {