dotnet-installer/src/Microsoft.DotNet.ProjectModel/DependencyContextBuilder.cs

169 lines
6.5 KiB
C#
Raw Normal View History

// 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;
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,
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()))
.ToDictionary(dependency => dependency.Name);
2016-03-04 17:13:04 +00:00
return new DependencyContext(
target.DotNetFrameworkName,
runtime,
false,
GetCompilationOptions(compilerOptions),
2016-03-04 17:13:04 +00:00
GetLibraries(compilationExports, dependencyLookup, runtime: false).Cast<CompilationLibrary>().ToArray(),
GetLibraries(runtimeExports, dependencyLookup, runtime: true).Cast<RuntimeLibrary>().ToArray(),
2016-03-01 23:11:52 +00:00
new KeyValuePair<string, string[]>[0]);
2015-12-17 23:04:18 +00:00
}
private static CompilationOptions GetCompilationOptions(CommonCompilerOptions compilerOptions)
2015-12-17 23:04:18 +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,
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,
IDictionary<string, Dependency> dependencyLookup,
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));
}
2016-03-04 17:13:04 +00:00
private Library GetLibrary(LibraryExport export,
bool runtime,
IDictionary<string, Dependency> dependencyLookup)
{
2016-02-10 18:07:22 +00:00
var type = export.Library.Identity.Type;
2015-12-17 23:04:18 +00:00
var serviceable = (export.Library as PackageDescription)?.Library.IsServiceable ?? false;
var libraryDependencies = new List<Dependency>();
2015-12-17 23:04:18 +00:00
var libraryAssets = runtime ? export.RuntimeAssemblies : export.CompilationAssemblies;
2016-03-04 18:19:45 +00:00
foreach (var libraryDependency in export.Library.Dependencies)
{
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;
}
Dependency dependency;
if (dependencyLookup.TryGetValue(libraryDependency.Name, out dependency))
{
libraryDependencies.Add(dependency);
}
}
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);
}
else
{
assemblies = libraryAssets.Select(libraryAsset => libraryAsset.RelativePath).ToArray();
}
2015-12-17 23:04:18 +00:00
if (runtime)
{
return new RuntimeLibrary(
2016-02-10 18:07:22 +00:00
type.ToString().ToLowerInvariant(),
export.Library.Identity.Name,
export.Library.Identity.Version.ToString(),
export.Library.Hash,
2016-03-02 23:31:13 +00:00
assemblies.Select(RuntimeAssembly.Create).ToArray(),
new RuntimeTarget[0],
libraryDependencies.ToArray(),
serviceable
);
}
else
{
return new CompilationLibrary(
2016-02-10 18:07:22 +00:00
type.ToString().ToLowerInvariant(),
export.Library.Identity.Name,
export.Library.Identity.Version.ToString(),
export.Library.Hash,
assemblies,
libraryDependencies.ToArray(),
serviceable
);
}
2015-12-17 23:04:18 +00:00
}
2016-02-10 18:07:22 +00:00
2016-03-04 17:13:04 +00:00
private string[] ResolveReferenceAssembliesPath(IEnumerable<LibraryAsset> libraryAssets)
2016-02-10 18:07:22 +00:00
{
var resolvedPaths = new List<string>();
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))
{
resolvedPaths.Add(libraryAsset.ResolvedPath.Substring(referenceAssembliesPath.Length));
}
else
{
resolvedPaths.Add(Path.GetFileName(libraryAsset.ResolvedPath));
}
}
return resolvedPaths.ToArray();
}
2015-12-17 23:04:18 +00:00
}
}