2016-01-07 23:11:47 +00:00
|
|
|
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
|
|
|
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
|
|
|
|
2015-12-17 23:04:18 +00:00
|
|
|
|
using System.Collections.Generic;
|
2016-02-10 18:07:22 +00:00
|
|
|
|
using System.IO;
|
2015-12-17 23:04:18 +00:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using Microsoft.DotNet.ProjectModel;
|
|
|
|
|
using Microsoft.DotNet.ProjectModel.Compilation;
|
|
|
|
|
using Microsoft.DotNet.ProjectModel.Graph;
|
2016-02-10 18:07:22 +00:00
|
|
|
|
using Microsoft.DotNet.ProjectModel.Resolution;
|
|
|
|
|
using Microsoft.DotNet.ProjectModel.Utilities;
|
2015-12-21 18:36:20 +00:00
|
|
|
|
using NuGet.Frameworks;
|
2015-12-17 23:04:18 +00:00
|
|
|
|
|
|
|
|
|
namespace Microsoft.Extensions.DependencyModel
|
|
|
|
|
{
|
2016-03-04 17:13:04 +00:00
|
|
|
|
public class DependencyContextBuilder
|
2015-12-17 23:04:18 +00:00
|
|
|
|
{
|
2016-03-04 17:13:04 +00:00
|
|
|
|
private readonly string _referenceAssembliesPath;
|
|
|
|
|
|
|
|
|
|
public DependencyContextBuilder() : this(FrameworkReferenceResolver.Default.ReferenceAssembliesPath)
|
2015-12-17 23:04:18 +00:00
|
|
|
|
{
|
2016-03-04 17:13:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DependencyContextBuilder(string referenceAssembliesPath)
|
|
|
|
|
{
|
|
|
|
|
_referenceAssembliesPath = referenceAssembliesPath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DependencyContext Build(CommonCompilerOptions compilerOptions,
|
|
|
|
|
IEnumerable<LibraryExport> compilationExports,
|
|
|
|
|
IEnumerable<LibraryExport> runtimeExports,
|
2016-03-09 00:46:50 +00:00
|
|
|
|
bool portable,
|
2016-03-04 17:13:04 +00:00
|
|
|
|
NuGetFramework target,
|
|
|
|
|
string runtime)
|
|
|
|
|
{
|
|
|
|
|
if (compilationExports == null)
|
|
|
|
|
{
|
|
|
|
|
compilationExports = Enumerable.Empty<LibraryExport>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var dependencyLookup = compilationExports
|
|
|
|
|
.Concat(runtimeExports)
|
|
|
|
|
.Select(export => export.Library.Identity)
|
|
|
|
|
.Distinct()
|
|
|
|
|
.Select(identity => new Dependency(identity.Name, identity.Version.ToString()))
|
2015-12-21 18:36:20 +00:00
|
|
|
|
.ToDictionary(dependency => dependency.Name);
|
|
|
|
|
|
2016-03-09 00:46:50 +00:00
|
|
|
|
var compilationOptions = compilerOptions != null
|
|
|
|
|
? GetCompilationOptions(compilerOptions)
|
|
|
|
|
: CompilationOptions.Default;
|
2016-03-04 17:13:04 +00:00
|
|
|
|
return new DependencyContext(
|
|
|
|
|
target.DotNetFrameworkName,
|
|
|
|
|
runtime,
|
2016-03-09 00:46:50 +00:00
|
|
|
|
portable,
|
|
|
|
|
compilationOptions,
|
2016-03-07 18:51:40 +00:00
|
|
|
|
GetLibraries(compilationExports, dependencyLookup, runtime: false).Cast<CompilationLibrary>(),
|
|
|
|
|
GetLibraries(runtimeExports, dependencyLookup, runtime: true).Cast<RuntimeLibrary>(),
|
2016-03-10 18:12:43 +00:00
|
|
|
|
new RuntimeFallbacks[] {});
|
2015-12-17 23:04:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-12-21 18:36:20 +00:00
|
|
|
|
private static CompilationOptions GetCompilationOptions(CommonCompilerOptions compilerOptions)
|
2015-12-17 23:04:18 +00:00
|
|
|
|
{
|
2015-12-21 18:36:20 +00:00
|
|
|
|
return new CompilationOptions(compilerOptions.Defines,
|
|
|
|
|
compilerOptions.LanguageVersion,
|
|
|
|
|
compilerOptions.Platform,
|
|
|
|
|
compilerOptions.AllowUnsafe,
|
|
|
|
|
compilerOptions.WarningsAsErrors,
|
|
|
|
|
compilerOptions.Optimize,
|
|
|
|
|
compilerOptions.KeyFile,
|
|
|
|
|
compilerOptions.DelaySign,
|
|
|
|
|
compilerOptions.PublicSign,
|
2016-03-02 23:53:59 +00:00
|
|
|
|
compilerOptions.DebugType,
|
2016-01-08 19:03:14 +00:00
|
|
|
|
compilerOptions.EmitEntryPoint,
|
|
|
|
|
compilerOptions.GenerateXmlDocumentation);
|
2015-12-17 23:04:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-04 17:13:04 +00:00
|
|
|
|
private IEnumerable<Library> GetLibraries(IEnumerable<LibraryExport> exports,
|
2015-12-21 18:36:20 +00:00
|
|
|
|
IDictionary<string, Dependency> dependencyLookup,
|
2016-01-07 23:11:47 +00:00
|
|
|
|
bool runtime)
|
2015-12-17 23:04:18 +00:00
|
|
|
|
{
|
2016-03-04 17:13:04 +00:00
|
|
|
|
return exports.Select(export => GetLibrary(export, runtime, dependencyLookup));
|
2015-12-21 18:36:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-04 17:13:04 +00:00
|
|
|
|
private Library GetLibrary(LibraryExport export,
|
2016-01-07 23:11:47 +00:00
|
|
|
|
bool runtime,
|
2015-12-21 18:36:20 +00:00
|
|
|
|
IDictionary<string, Dependency> dependencyLookup)
|
|
|
|
|
{
|
2016-02-10 18:07:22 +00:00
|
|
|
|
var type = export.Library.Identity.Type;
|
2015-12-21 18:36:20 +00:00
|
|
|
|
|
2015-12-17 23:04:18 +00:00
|
|
|
|
var serviceable = (export.Library as PackageDescription)?.Library.IsServiceable ?? false;
|
2016-03-08 17:22:17 +00:00
|
|
|
|
var libraryDependencies = new HashSet<Dependency>();
|
2015-12-17 23:04:18 +00:00
|
|
|
|
|
2016-01-07 23:11:47 +00:00
|
|
|
|
var libraryAssets = runtime ? export.RuntimeAssemblies : export.CompilationAssemblies;
|
|
|
|
|
|
2016-03-04 18:19:45 +00:00
|
|
|
|
foreach (var libraryDependency in export.Library.Dependencies)
|
2015-12-21 18:36:20 +00:00
|
|
|
|
{
|
2016-03-04 18:19:45 +00:00
|
|
|
|
// skip build time dependencies
|
|
|
|
|
if (!libraryDependency.Type.HasFlag(
|
|
|
|
|
LibraryDependencyTypeFlag.MainReference |
|
|
|
|
|
LibraryDependencyTypeFlag.MainExport |
|
|
|
|
|
LibraryDependencyTypeFlag.RuntimeComponent |
|
|
|
|
|
LibraryDependencyTypeFlag.BecomesNupkgDependency))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2016-02-05 22:27:09 +00:00
|
|
|
|
|
2015-12-21 18:36:20 +00:00
|
|
|
|
Dependency dependency;
|
|
|
|
|
if (dependencyLookup.TryGetValue(libraryDependency.Name, out dependency))
|
|
|
|
|
{
|
|
|
|
|
libraryDependencies.Add(dependency);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-07 18:51:40 +00:00
|
|
|
|
IEnumerable<string> assemblies;
|
2016-03-04 17:13:04 +00:00
|
|
|
|
if (type == LibraryType.ReferenceAssembly)
|
2016-02-10 18:07:22 +00:00
|
|
|
|
{
|
|
|
|
|
assemblies = ResolveReferenceAssembliesPath(libraryAssets);
|
|
|
|
|
}
|
2015-12-21 18:36:20 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
2016-03-07 18:51:40 +00:00
|
|
|
|
assemblies = libraryAssets.Select(libraryAsset => libraryAsset.RelativePath);
|
2015-12-21 18:36:20 +00:00
|
|
|
|
}
|
2015-12-17 23:04:18 +00:00
|
|
|
|
|
2016-01-07 23:11:47 +00:00
|
|
|
|
if (runtime)
|
|
|
|
|
{
|
|
|
|
|
return new RuntimeLibrary(
|
2016-02-10 18:07:22 +00:00
|
|
|
|
type.ToString().ToLowerInvariant(),
|
2016-01-07 23:11:47 +00:00
|
|
|
|
export.Library.Identity.Name,
|
|
|
|
|
export.Library.Identity.Version.ToString(),
|
|
|
|
|
export.Library.Hash,
|
2016-03-07 18:51:40 +00:00
|
|
|
|
assemblies.Select(RuntimeAssembly.Create),
|
2016-03-11 22:49:23 +00:00
|
|
|
|
export.NativeLibraries.Select(l => l.RelativePath),
|
2016-03-07 18:51:40 +00:00
|
|
|
|
export.ResourceAssemblies.Select(CreateResourceAssembly),
|
|
|
|
|
export.RuntimeTargets.Select(CreateRuntimeTarget),
|
|
|
|
|
libraryDependencies,
|
2016-01-07 23:11:47 +00:00
|
|
|
|
serviceable
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return new CompilationLibrary(
|
2016-02-10 18:07:22 +00:00
|
|
|
|
type.ToString().ToLowerInvariant(),
|
2016-01-07 23:11:47 +00:00
|
|
|
|
export.Library.Identity.Name,
|
|
|
|
|
export.Library.Identity.Version.ToString(),
|
|
|
|
|
export.Library.Hash,
|
|
|
|
|
assemblies,
|
2016-03-07 18:51:40 +00:00
|
|
|
|
libraryDependencies,
|
2016-01-07 23:11:47 +00:00
|
|
|
|
serviceable
|
|
|
|
|
);
|
|
|
|
|
}
|
2015-12-17 23:04:18 +00:00
|
|
|
|
}
|
2016-02-10 18:07:22 +00:00
|
|
|
|
|
2016-03-07 18:51:40 +00:00
|
|
|
|
private ResourceAssembly CreateResourceAssembly(LibraryResourceAssembly resourceAssembly)
|
|
|
|
|
{
|
|
|
|
|
return new ResourceAssembly(
|
|
|
|
|
path: resourceAssembly.Asset.RelativePath,
|
|
|
|
|
locale: resourceAssembly.Locale
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private RuntimeTarget CreateRuntimeTarget(LibraryRuntimeTarget runtimeTarget)
|
|
|
|
|
{
|
|
|
|
|
return new RuntimeTarget(
|
|
|
|
|
runtime: runtimeTarget.Runtime,
|
|
|
|
|
assemblies: runtimeTarget.RuntimeAssemblies.Select(a => RuntimeAssembly.Create(a.RelativePath)),
|
|
|
|
|
nativeLibraries: runtimeTarget.NativeLibraries.Select(l => l.RelativePath)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IEnumerable<string> ResolveReferenceAssembliesPath(IEnumerable<LibraryAsset> libraryAssets)
|
2016-02-10 18:07:22 +00:00
|
|
|
|
{
|
|
|
|
|
var referenceAssembliesPath =
|
2016-03-04 17:13:04 +00:00
|
|
|
|
PathUtility.EnsureTrailingSlash(_referenceAssembliesPath);
|
2016-02-10 18:07:22 +00:00
|
|
|
|
foreach (var libraryAsset in libraryAssets)
|
|
|
|
|
{
|
|
|
|
|
// If resolved path is under ReferenceAssembliesPath store it as a relative to it
|
|
|
|
|
// if not, save only assembly name and try to find it somehow later
|
|
|
|
|
if (libraryAsset.ResolvedPath.StartsWith(referenceAssembliesPath))
|
|
|
|
|
{
|
2016-03-07 18:51:40 +00:00
|
|
|
|
yield return libraryAsset.ResolvedPath.Substring(referenceAssembliesPath.Length);
|
2016-02-10 18:07:22 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2016-03-07 18:51:40 +00:00
|
|
|
|
yield return Path.GetFileName(libraryAsset.ResolvedPath);
|
2016-02-10 18:07:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-12-17 23:04:18 +00:00
|
|
|
|
}
|
|
|
|
|
}
|