// 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; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using Microsoft.Extensions.PlatformAbstractions; namespace Microsoft.AspNetCore.Mvc.Infrastructure { public class DnxAssemblyProvider { private readonly ILibraryManager _libraryManager; public DnxAssemblyProvider(ILibraryManager libraryManager) { _libraryManager = libraryManager; } /// /// Gets the set of assembly names that are used as root for discovery of /// MVC controllers, view components and views. /// // DefaultControllerTypeProvider uses CandidateAssemblies to determine if the base type of a POCO controller // lives in an assembly that references MVC. CandidateAssemblies excludes all assemblies from the // ReferenceAssemblies set. Consequently adding WebApiCompatShim to this set would cause the ApiController to // fail this test. protected virtual HashSet ReferenceAssemblies { get; } = new HashSet(StringComparer.Ordinal) { "Microsoft.AspNetCore.Mvc", "Microsoft.AspNetCore.Mvc.Abstractions", "Microsoft.AspNetCore.Mvc.ApiExplorer", "Microsoft.AspNetCore.Mvc.Core", "Microsoft.AspNetCore.Mvc.Cors", "Microsoft.AspNetCore.Mvc.DataAnnotations", "Microsoft.AspNetCore.Mvc.Formatters.Json", "Microsoft.AspNetCore.Mvc.Formatters.Xml", "Microsoft.AspNetCore.Mvc.Localization", "Microsoft.AspNetCore.Mvc.Razor", "Microsoft.AspNetCore.Mvc.Razor.Host", "Microsoft.AspNetCore.Mvc.TagHelpers", "Microsoft.AspNetCore.Mvc.ViewFeatures" }; /// public IEnumerable CandidateAssemblies { get { return GetCandidateLibraries().SelectMany(l => l.Assemblies) .Select(Load); } } /// /// Returns a list of libraries that references the assemblies in . /// By default it returns all assemblies that reference any of the primary MVC assemblies /// while ignoring MVC assemblies. /// /// A set of . protected virtual IEnumerable GetCandidateLibraries() { if (ReferenceAssemblies == null) { return Enumerable.Empty(); } // GetReferencingLibraries returns the transitive closure of referencing assemblies // for a given assembly. return ReferenceAssemblies.SelectMany(_libraryManager.GetReferencingLibraries) .Distinct() .Where(IsCandidateLibrary); } private static Assembly Load(AssemblyName assemblyName) { return Assembly.Load(assemblyName); } private bool IsCandidateLibrary(Library library) { Debug.Assert(ReferenceAssemblies != null); return !ReferenceAssemblies.Contains(library.Name); } } }