// Copyright (c) Microsoft Open Technologies, Inc. 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.Framework.Runtime;
namespace Microsoft.AspNet.Mvc
{
public class DefaultAssemblyProvider : IAssemblyProvider
{
private readonly ILibraryManager _libraryManager;
public DefaultAssemblyProvider(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.AspNet.Mvc",
"Microsoft.AspNet.Mvc.Abstractions",
"Microsoft.AspNet.Mvc.Core",
"Microsoft.AspNet.Mvc.Razor",
"Microsoft.AspNet.Mvc.Razor.Host",
"Microsoft.AspNet.Mvc.TagHelpers",
"Microsoft.AspNet.Mvc.Xml",
"Microsoft.AspNet.PageExecutionInstrumentation.Interfaces",
};
///
public IEnumerable CandidateAssemblies
{
get
{
return GetCandidateLibraries().SelectMany(l => l.LoadableAssemblies)
.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(ILibraryInformation library)
{
Debug.Assert(ReferenceAssemblies != null);
return !ReferenceAssemblies.Contains(library.Name);
}
}
}