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 ;
using System.Linq ;
using Microsoft.DotNet.ProjectModel ;
using Microsoft.DotNet.ProjectModel.Compilation ;
using Microsoft.DotNet.ProjectModel.Graph ;
2015-12-21 10:36:20 -08:00
using NuGet.Frameworks ;
2015-12-17 15:04:18 -08:00
namespace Microsoft.Extensions.DependencyModel
{
public static class DependencyContextBuilder
{
2015-12-21 10:36:20 -08:00
public static DependencyContext Build ( CommonCompilerOptions compilerOptions , LibraryExporter libraryExporter , string configuration , NuGetFramework target , string runtime )
2015-12-17 15:04:18 -08:00
{
2016-02-09 12:33:47 -08:00
var dependencies = libraryExporter . GetAllExports ( ) ;
2015-12-17 15:04:18 -08:00
2015-12-21 10:36:20 -08:00
// Sometimes we have package and reference assembly with the same name (System.Runtime for example) thats why we
// deduplicating them prefering reference assembly
var dependencyLookup = dependencies
. OrderBy ( export = > export . Library . Identity . Type = = LibraryType . ReferenceAssembly )
. GroupBy ( export = > export . Library . Identity . Name )
. Select ( exports = > exports . First ( ) )
. Select ( export = > new Dependency ( export . Library . Identity . Name , export . Library . Identity . Version . ToString ( ) ) )
. ToDictionary ( dependency = > dependency . Name ) ;
return new DependencyContext ( target . DotNetFrameworkName , runtime ,
GetCompilationOptions ( compilerOptions ) ,
2016-01-07 15:11:47 -08:00
GetLibraries ( dependencies , dependencyLookup , target , configuration , runtime : false ) . Cast < CompilationLibrary > ( ) . ToArray ( ) ,
GetLibraries ( dependencies , dependencyLookup , target , configuration , runtime : true ) . Cast < RuntimeLibrary > ( ) . ToArray ( ) ) ;
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-01-08 11:03:14 -08:00
compilerOptions . EmitEntryPoint ,
compilerOptions . GenerateXmlDocumentation ) ;
2015-12-17 15:04:18 -08:00
}
2016-01-07 15:11:47 -08:00
private static IEnumerable < Library > GetLibraries ( IEnumerable < LibraryExport > dependencies ,
2015-12-21 10:36:20 -08:00
IDictionary < string , Dependency > dependencyLookup ,
NuGetFramework target ,
string configuration ,
2016-01-07 15:11:47 -08:00
bool runtime )
2015-12-17 15:04:18 -08:00
{
2016-01-07 15:11:47 -08:00
return dependencies . Select ( export = > GetLibrary ( export , target , configuration , runtime , dependencyLookup ) ) ;
2015-12-21 10:36:20 -08:00
}
private static Library GetLibrary ( LibraryExport export ,
NuGetFramework target ,
string configuration ,
2016-01-07 15:11:47 -08:00
bool runtime ,
2015-12-21 10:36:20 -08:00
IDictionary < string , Dependency > dependencyLookup )
{
var type = export . Library . Identity . Type . Value . ToLowerInvariant ( ) ;
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-02-05 14:27:09 -08:00
foreach ( var libraryDependenciesGroup in export . Library . Dependencies . GroupBy ( d = > d . Name ) )
2015-12-21 10:36:20 -08:00
{
2016-02-05 14:27:09 -08:00
LibraryRange libraryDependency = libraryDependenciesGroup
. OrderByDescending ( d = > d . Target = = LibraryType . ReferenceAssembly )
. First ( ) ;
2015-12-21 10:36:20 -08:00
Dependency dependency ;
if ( dependencyLookup . TryGetValue ( libraryDependency . Name , out dependency ) )
{
libraryDependencies . Add ( dependency ) ;
}
}
string [ ] assemblies ;
if ( type = = "project" )
{
2016-01-11 09:37:24 -08:00
var isExe = ( ( ProjectDescription ) export . Library )
2015-12-21 10:36:20 -08:00
. Project
. GetCompilerOptions ( target , configuration )
. EmitEntryPoint
. GetValueOrDefault ( false ) ;
2016-01-08 09:02:04 -08:00
isExe & = target . IsDesktop ( ) ;
2016-01-11 09:37:24 -08:00
assemblies = new [ ] { export . Library . Identity . Name + ( isExe ? ".exe" : ".dll" ) } ;
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 (
type ,
export . Library . Identity . Name ,
export . Library . Identity . Version . ToString ( ) ,
export . Library . Hash ,
assemblies ,
libraryDependencies . ToArray ( ) ,
serviceable
) ;
}
else
{
return new CompilationLibrary (
type ,
export . Library . Identity . Name ,
export . Library . Identity . Version . ToString ( ) ,
export . Library . Hash ,
assemblies ,
libraryDependencies . ToArray ( ) ,
serviceable
) ;
}
2015-12-17 15:04:18 -08:00
}
}
}