2016-01-07 15:11:47 -08: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 15:04:18 -08:00
using System.Collections.Generic ;
2016-02-10 10:07:22 -08:00
using System.IO ;
2015-12-17 15:04:18 -08:00
using System.Linq ;
using Microsoft.DotNet.ProjectModel ;
using Microsoft.DotNet.ProjectModel.Compilation ;
using Microsoft.DotNet.ProjectModel.Graph ;
2016-02-10 10:07:22 -08:00
using Microsoft.DotNet.ProjectModel.Resolution ;
using Microsoft.DotNet.ProjectModel.Utilities ;
2015-12-21 10:36:20 -08:00
using NuGet.Frameworks ;
2015-12-17 15:04:18 -08:00
namespace Microsoft.Extensions.DependencyModel
{
2016-03-04 09:13:04 -08:00
public class DependencyContextBuilder
2015-12-17 15:04:18 -08:00
{
2016-03-04 09:13:04 -08:00
private readonly string _referenceAssembliesPath ;
public DependencyContextBuilder ( ) : this ( FrameworkReferenceResolver . Default . ReferenceAssembliesPath )
2015-12-17 15:04:18 -08:00
{
2016-03-04 09:13:04 -08: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 ( ) ) )
2015-12-21 10:36:20 -08:00
. ToDictionary ( dependency = > dependency . Name ) ;
2016-03-04 09:13:04 -08:00
return new DependencyContext (
target . DotNetFrameworkName ,
runtime ,
false ,
2015-12-21 10:36:20 -08:00
GetCompilationOptions ( compilerOptions ) ,
2016-03-04 09:13:04 -08:00
GetLibraries ( compilationExports , dependencyLookup , runtime : false ) . Cast < CompilationLibrary > ( ) . ToArray ( ) ,
GetLibraries ( runtimeExports , dependencyLookup , runtime : true ) . Cast < RuntimeLibrary > ( ) . ToArray ( ) ,
2016-03-01 15:11:52 -08:00
new KeyValuePair < string , string [ ] > [ 0 ] ) ;
2015-12-17 15:04:18 -08:00
}
2015-12-21 10:36:20 -08:00
private static CompilationOptions GetCompilationOptions ( CommonCompilerOptions compilerOptions )
2015-12-17 15:04:18 -08:00
{
2015-12-21 10:36:20 -08: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 15:53:59 -08:00
compilerOptions . DebugType ,
2016-01-08 11:03:14 -08:00
compilerOptions . EmitEntryPoint ,
compilerOptions . GenerateXmlDocumentation ) ;
2015-12-17 15:04:18 -08:00
}
2016-03-04 09:13:04 -08:00
private IEnumerable < Library > GetLibraries ( IEnumerable < LibraryExport > exports ,
2015-12-21 10:36:20 -08:00
IDictionary < string , Dependency > dependencyLookup ,
2016-01-07 15:11:47 -08:00
bool runtime )
2015-12-17 15:04:18 -08:00
{
2016-03-04 09:13:04 -08:00
return exports . Select ( export = > GetLibrary ( export , runtime , dependencyLookup ) ) ;
2015-12-21 10:36:20 -08:00
}
2016-03-04 09:13:04 -08:00
private Library GetLibrary ( LibraryExport export ,
2016-01-07 15:11:47 -08:00
bool runtime ,
2015-12-21 10:36:20 -08:00
IDictionary < string , Dependency > dependencyLookup )
{
2016-02-10 10:07:22 -08:00
var type = export . Library . Identity . Type ;
2015-12-21 10:36:20 -08:00
2015-12-17 15:04:18 -08:00
var serviceable = ( export . Library as PackageDescription ) ? . Library . IsServiceable ? ? false ;
2015-12-21 10:36:20 -08:00
var libraryDependencies = new List < Dependency > ( ) ;
2015-12-17 15:04:18 -08:00
2016-01-07 15:11:47 -08:00
var libraryAssets = runtime ? export . RuntimeAssemblies : export . CompilationAssemblies ;
2016-03-04 10:19:45 -08:00
foreach ( var libraryDependency in export . Library . Dependencies )
2015-12-21 10:36:20 -08:00
{
2016-03-04 10:19:45 -08:00
// skip build time dependencies
if ( ! libraryDependency . Type . HasFlag (
LibraryDependencyTypeFlag . MainReference |
LibraryDependencyTypeFlag . MainExport |
LibraryDependencyTypeFlag . RuntimeComponent |
LibraryDependencyTypeFlag . BecomesNupkgDependency ) )
{
continue ;
}
2016-02-05 14:27:09 -08:00
2015-12-21 10:36:20 -08:00
Dependency dependency ;
if ( dependencyLookup . TryGetValue ( libraryDependency . Name , out dependency ) )
{
libraryDependencies . Add ( dependency ) ;
}
}
string [ ] assemblies ;
2016-03-04 09:13:04 -08:00
if ( type = = LibraryType . ReferenceAssembly )
2016-02-10 10:07:22 -08:00
{
assemblies = ResolveReferenceAssembliesPath ( libraryAssets ) ;
}
2015-12-21 10:36:20 -08:00
else
{
assemblies = libraryAssets . Select ( libraryAsset = > libraryAsset . RelativePath ) . ToArray ( ) ;
}
2015-12-17 15:04:18 -08:00
2016-01-07 15:11:47 -08:00
if ( runtime )
{
return new RuntimeLibrary (
2016-02-10 10:07:22 -08:00
type . ToString ( ) . ToLowerInvariant ( ) ,
2016-01-07 15:11:47 -08:00
export . Library . Identity . Name ,
export . Library . Identity . Version . ToString ( ) ,
export . Library . Hash ,
2016-03-02 15:31:13 -08:00
assemblies . Select ( RuntimeAssembly . Create ) . ToArray ( ) ,
new RuntimeTarget [ 0 ] ,
2016-01-07 15:11:47 -08:00
libraryDependencies . ToArray ( ) ,
serviceable
) ;
}
else
{
return new CompilationLibrary (
2016-02-10 10:07:22 -08:00
type . ToString ( ) . ToLowerInvariant ( ) ,
2016-01-07 15:11:47 -08:00
export . Library . Identity . Name ,
export . Library . Identity . Version . ToString ( ) ,
export . Library . Hash ,
assemblies ,
libraryDependencies . ToArray ( ) ,
serviceable
) ;
}
2015-12-17 15:04:18 -08:00
}
2016-02-10 10:07:22 -08:00
2016-03-04 09:13:04 -08:00
private string [ ] ResolveReferenceAssembliesPath ( IEnumerable < LibraryAsset > libraryAssets )
2016-02-10 10:07:22 -08:00
{
var resolvedPaths = new List < string > ( ) ;
var referenceAssembliesPath =
2016-03-04 09:13:04 -08:00
PathUtility . EnsureTrailingSlash ( _referenceAssembliesPath ) ;
2016-02-10 10:07:22 -08: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 15:04:18 -08:00
}
}