From 0e41c93ca799f3bc1d21cbd58c30a279550186e6 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Thu, 7 Jan 2016 15:11:47 -0800 Subject: [PATCH] Split library type, add path resolution --- .../DependencyContextBuilder.cs | 52 +++++++++++++------ .../CompilationLibrary.cs | 49 +++++++++++++++++ .../CompilationOptions.cs | 5 +- .../DependencyContext.cs | 6 +-- .../DependencyContextReader.cs | 19 ++++--- .../DependencyContextStrings.cs | 3 ++ .../DependencyContextWriter.cs | 43 ++++++++++++--- .../Library.cs | 8 +-- .../RuntimeAssembly.cs | 26 ++++++++++ .../RuntimeLibrary.cs | 19 +++++++ .../project.json | 4 +- 11 files changed, 192 insertions(+), 42 deletions(-) create mode 100644 src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs create mode 100644 src/Microsoft.Extensions.DependencyModel/RuntimeAssembly.cs create mode 100644 src/Microsoft.Extensions.DependencyModel/RuntimeLibrary.cs diff --git a/src/Microsoft.DotNet.ProjectModel/DependencyContextBuilder.cs b/src/Microsoft.DotNet.ProjectModel/DependencyContextBuilder.cs index 005d24f81..653b33e0a 100644 --- a/src/Microsoft.DotNet.ProjectModel/DependencyContextBuilder.cs +++ b/src/Microsoft.DotNet.ProjectModel/DependencyContextBuilder.cs @@ -1,7 +1,8 @@ -using System; +// 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. + using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using Microsoft.DotNet.ProjectModel; using Microsoft.DotNet.ProjectModel.Compilation; using Microsoft.DotNet.ProjectModel.Graph; @@ -26,8 +27,8 @@ namespace Microsoft.Extensions.DependencyModel return new DependencyContext(target.DotNetFrameworkName, runtime, GetCompilationOptions(compilerOptions), - GetLibraries(dependencies, dependencyLookup, target, configuration, export => export.CompilationAssemblies), - GetLibraries(dependencies, dependencyLookup, target, configuration, export => export.RuntimeAssemblies)); + GetLibraries(dependencies, dependencyLookup, target, configuration, runtime: false).Cast().ToArray(), + GetLibraries(dependencies, dependencyLookup, target, configuration, runtime: true).Cast().ToArray()); } private static CompilationOptions GetCompilationOptions(CommonCompilerOptions compilerOptions) @@ -44,19 +45,19 @@ namespace Microsoft.Extensions.DependencyModel compilerOptions.EmitEntryPoint); } - private static Library[] GetLibraries(IEnumerable dependencies, + private static IEnumerable GetLibraries(IEnumerable dependencies, IDictionary dependencyLookup, NuGetFramework target, string configuration, - Func> assemblySelector) + bool runtime) { - return dependencies.Select(export => GetLibrary(export, target, configuration, assemblySelector(export), dependencyLookup)).ToArray(); + return dependencies.Select(export => GetLibrary(export, target, configuration, runtime, dependencyLookup)); } private static Library GetLibrary(LibraryExport export, NuGetFramework target, string configuration, - IEnumerable libraryAssets, + bool runtime, IDictionary dependencyLookup) { var type = export.Library.Identity.Type.Value.ToLowerInvariant(); @@ -64,6 +65,8 @@ namespace Microsoft.Extensions.DependencyModel var serviceable = (export.Library as PackageDescription)?.Library.IsServiceable ?? false; var libraryDependencies = new List(); + var libraryAssets = runtime ? export.RuntimeAssemblies : export.CompilationAssemblies; + foreach (var libraryDependency in export.Library.Dependencies) { Dependency dependency; @@ -89,15 +92,30 @@ namespace Microsoft.Extensions.DependencyModel assemblies = libraryAssets.Select(libraryAsset => libraryAsset.RelativePath).ToArray(); } - return new Library( - type, - export.Library.Identity.Name, - export.Library.Identity.Version.ToString(), - export.Library.Hash, - assemblies, - libraryDependencies.ToArray(), - serviceable - ); + 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 + ); + } } } } diff --git a/src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs b/src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs new file mode 100644 index 000000000..dcba6361f --- /dev/null +++ b/src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs @@ -0,0 +1,49 @@ +// 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. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; + +namespace Microsoft.Extensions.DependencyModel +{ + public class CompilationLibrary : Library + { + private static Lazy _refsLocation = new Lazy(GetRefsLocation); + + public CompilationLibrary(string libraryType, string packageName, string version, string hash, string[] assemblies, Dependency[] dependencies, bool serviceable) + : base(libraryType, packageName, version, hash, dependencies, serviceable) + { + Assemblies = assemblies; + } + + public IReadOnlyList Assemblies { get; } + + public IEnumerable ResolveReferencePaths() + { + var basePath = _refsLocation.Value; + + foreach (var assembly in Assemblies) + { + var fullName = Path.Combine(basePath, Path.GetFileName(assembly)); + if (!File.Exists(fullName)) + { + throw new InvalidOperationException($"Can not resolve assembly {assembly} location"); + } + yield return fullName; + } + } + + private static string GetRefsLocation() + { + var entryAssembly = (Assembly)typeof(Assembly).GetTypeInfo().GetDeclaredMethod("GetEntryAssembly").Invoke(null, null); + if (entryAssembly == null) + { + throw new InvalidOperationException("Could not determine entry assembly"); + } + + return Path.Combine(Path.GetDirectoryName(entryAssembly.Location), "refs"); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.DependencyModel/CompilationOptions.cs b/src/Microsoft.Extensions.DependencyModel/CompilationOptions.cs index 677879436..686b9a7ea 100644 --- a/src/Microsoft.Extensions.DependencyModel/CompilationOptions.cs +++ b/src/Microsoft.Extensions.DependencyModel/CompilationOptions.cs @@ -1,4 +1,7 @@ -using System.Collections.Generic; +// 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. + +using System.Collections.Generic; namespace Microsoft.Extensions.DependencyModel { diff --git a/src/Microsoft.Extensions.DependencyModel/DependencyContext.cs b/src/Microsoft.Extensions.DependencyModel/DependencyContext.cs index 1294d70fc..229a0dbcb 100644 --- a/src/Microsoft.Extensions.DependencyModel/DependencyContext.cs +++ b/src/Microsoft.Extensions.DependencyModel/DependencyContext.cs @@ -14,7 +14,7 @@ namespace Microsoft.Extensions.DependencyModel private static Lazy _defaultContext = new Lazy(LoadDefault); - public DependencyContext(string target, string runtime, CompilationOptions compilationOptions, Library[] compileLibraries, Library[] runtimeLibraries) + public DependencyContext(string target, string runtime, CompilationOptions compilationOptions, CompilationLibrary[] compileLibraries, RuntimeLibrary[] runtimeLibraries) { Target = target; Runtime = runtime; @@ -31,9 +31,9 @@ namespace Microsoft.Extensions.DependencyModel public CompilationOptions CompilationOptions { get; } - public IReadOnlyList CompileLibraries { get; } + public IReadOnlyList CompileLibraries { get; } - public IReadOnlyList RuntimeLibraries { get; } + public IReadOnlyList RuntimeLibraries { get; } private static DependencyContext LoadDefault() { diff --git a/src/Microsoft.Extensions.DependencyModel/DependencyContextReader.cs b/src/Microsoft.Extensions.DependencyModel/DependencyContextReader.cs index 2d1a67137..37d700a35 100644 --- a/src/Microsoft.Extensions.DependencyModel/DependencyContextReader.cs +++ b/src/Microsoft.Extensions.DependencyModel/DependencyContextReader.cs @@ -38,8 +38,8 @@ namespace Microsoft.Extensions.DependencyModel compileTargetProperty.Key, runtimeTargetProperty.Key.Substring(compileTargetProperty.Key.Length + 1), ReadCompilationOptions((JObject)root[DependencyContextStrings.CompilationOptionsPropertName]), - ReadLibraries((JObject)runtimeTargetProperty.Value, true, libraryStubs), - ReadLibraries((JObject)compileTargetProperty.Value, false, libraryStubs) + ReadLibraries((JObject)compileTargetProperty.Value, false, libraryStubs).Cast().ToArray(), + ReadLibraries((JObject)runtimeTargetProperty.Value, true, libraryStubs).Cast().ToArray() ); } @@ -59,12 +59,12 @@ namespace Microsoft.Extensions.DependencyModel ); } - private Library[] ReadLibraries(JObject librariesObject, bool runtime, Dictionary libraryStubs) + private IEnumerable ReadLibraries(JObject librariesObject, bool runtime, Dictionary libraryStubs) { - return librariesObject.Properties().Select(property => ReadLibrary(property, runtime, libraryStubs)).ToArray(); + return librariesObject.Properties().Select(property => ReadLibrary(property, runtime, libraryStubs)); } - private Library ReadLibrary(JProperty property, bool runtime, Dictionary libraryStubs) + private Library ReadLibrary(JProperty property, bool runtime, Dictionary libraryStubs) { var nameWithVersion = property.Name; LibraryStub stub; @@ -84,7 +84,14 @@ namespace Microsoft.Extensions.DependencyModel var dependencies = ReadDependencies(libraryObject); var assemblies = ReadAssemblies(libraryObject, runtime); - return new Library(stub.Type, name, version, stub.Hash, assemblies, dependencies, stub.Serviceable); + if (runtime) + { + return new RuntimeLibrary(stub.Type, name, version, stub.Hash, assemblies, dependencies, stub.Serviceable); + } + else + { + return new CompilationLibrary(stub.Type, name, version, stub.Hash, assemblies, dependencies, stub.Serviceable); + } } private static string[] ReadAssemblies(JObject libraryObject, bool runtime) diff --git a/src/Microsoft.Extensions.DependencyModel/DependencyContextStrings.cs b/src/Microsoft.Extensions.DependencyModel/DependencyContextStrings.cs index c6f691fd8..b81f085da 100644 --- a/src/Microsoft.Extensions.DependencyModel/DependencyContextStrings.cs +++ b/src/Microsoft.Extensions.DependencyModel/DependencyContextStrings.cs @@ -1,3 +1,6 @@ +// 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. + namespace Microsoft.Extensions.DependencyModel { internal class DependencyContextStrings diff --git a/src/Microsoft.Extensions.DependencyModel/DependencyContextWriter.cs b/src/Microsoft.Extensions.DependencyModel/DependencyContextWriter.cs index e5b4e9f6f..29d61f57d 100644 --- a/src/Microsoft.Extensions.DependencyModel/DependencyContextWriter.cs +++ b/src/Microsoft.Extensions.DependencyModel/DependencyContextWriter.cs @@ -1,3 +1,6 @@ +// 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. + using System; using System.Collections.Generic; using System.IO; @@ -78,25 +81,49 @@ namespace Microsoft.Extensions.DependencyModel private JObject WriteTargets(DependencyContext context) { return new JObject( - new JProperty(context.Target, WriteTarget(context.CompileLibraries, false)), + new JProperty(context.Target, WriteTarget(context.CompileLibraries)), new JProperty(context.Target + DependencyContextStrings.VersionSeperator + context.Runtime, - WriteTarget(context.RuntimeLibraries, true)) + WriteTarget(context.RuntimeLibraries)) ); } - private JObject WriteTarget(IReadOnlyList libraries, bool runtime) + private JObject WriteTarget(IReadOnlyList libraries) { return new JObject( libraries.Select(library => - new JProperty(library.PackageName + DependencyContextStrings.VersionSeperator + library.Version, WriteTargetLibrary(library, runtime)))); + new JProperty(library.PackageName + DependencyContextStrings.VersionSeperator + library.Version, WriteTargetLibrary(library)))); } - private JObject WriteTargetLibrary(Library library, bool runtime) + private JObject WriteTargetLibrary(Library library) { + string propertyName; + string[] assemblies; + + var runtimeLibrary = library as RuntimeLibrary; + if (runtimeLibrary != null) + { + propertyName = DependencyContextStrings.RunTimeAssembliesKey; + assemblies = runtimeLibrary.Assemblies.Select(assembly => assembly.Path).ToArray(); + } + else + { + var compilationLibrary = library as CompilationLibrary; + if (compilationLibrary != null) + { + propertyName = DependencyContextStrings.CompileTimeAssembliesKey; + assemblies = compilationLibrary.Assemblies.ToArray(); + } + else + { + throw new NotSupportedException(); + } + } + + return new JObject( new JProperty(DependencyContextStrings.DependenciesPropertyName, WriteDependencies(library.Dependencies)), - new JProperty(runtime ? DependencyContextStrings.RunTimeAssembliesKey : DependencyContextStrings.CompileTimeAssembliesKey, - WriteAssemblies(library.Assemblies)) + new JProperty(propertyName, + WriteAssemblies(assemblies)) ); } @@ -115,7 +142,7 @@ namespace Microsoft.Extensions.DependencyModel private JObject WriteLibraries(DependencyContext context) { var allLibraries = - context.RuntimeLibraries.Concat(context.CompileLibraries) + context.RuntimeLibraries.Cast().Concat(context.CompileLibraries) .GroupBy(library => library.PackageName + DependencyContextStrings.VersionSeperator + library.Version); return new JObject(allLibraries.Select(libraries=> new JProperty(libraries.Key, WriteLibrary(libraries.First())))); diff --git a/src/Microsoft.Extensions.DependencyModel/Library.cs b/src/Microsoft.Extensions.DependencyModel/Library.cs index 3f37a69ec..1dcd2b169 100644 --- a/src/Microsoft.Extensions.DependencyModel/Library.cs +++ b/src/Microsoft.Extensions.DependencyModel/Library.cs @@ -1,20 +1,18 @@ // 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. -using System; using System.Collections.Generic; namespace Microsoft.Extensions.DependencyModel { - public struct Library + public class Library { - public Library(string libraryType, string packageName, string version, string hash, string[] assemblies, Dependency[] dependencies, bool serviceable) + public Library(string libraryType, string packageName, string version, string hash, Dependency[] dependencies, bool serviceable) { LibraryType = libraryType; PackageName = packageName; Version = version; Hash = hash; - Assemblies = assemblies; Dependencies = dependencies; Serviceable = serviceable; } @@ -27,8 +25,6 @@ namespace Microsoft.Extensions.DependencyModel public string Hash { get; } - public IReadOnlyList Assemblies { get; } - public IReadOnlyList Dependencies { get; } public bool Serviceable { get; } diff --git a/src/Microsoft.Extensions.DependencyModel/RuntimeAssembly.cs b/src/Microsoft.Extensions.DependencyModel/RuntimeAssembly.cs new file mode 100644 index 000000000..19c5499c9 --- /dev/null +++ b/src/Microsoft.Extensions.DependencyModel/RuntimeAssembly.cs @@ -0,0 +1,26 @@ +// 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. + +using System.IO; +using System.Reflection; + +namespace Microsoft.Extensions.DependencyModel +{ + public class RuntimeAssembly + { + public RuntimeAssembly(string path) + : this(new AssemblyName(System.IO.Path.GetFileNameWithoutExtension(path)), path) + { + } + + public RuntimeAssembly(AssemblyName name, string path) + { + Name = name; + Path = path; + } + + public AssemblyName Name { get; } + + public string Path { get; } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.DependencyModel/RuntimeLibrary.cs b/src/Microsoft.Extensions.DependencyModel/RuntimeLibrary.cs new file mode 100644 index 000000000..39369c6d5 --- /dev/null +++ b/src/Microsoft.Extensions.DependencyModel/RuntimeLibrary.cs @@ -0,0 +1,19 @@ +// 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. + +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.Extensions.DependencyModel +{ + public class RuntimeLibrary : Library + { + public RuntimeLibrary(string libraryType, string packageName, string version, string hash, string[] assemblies, Dependency[] dependencies, bool serviceable) + : base(libraryType, packageName, version, hash, dependencies, serviceable) + { + Assemblies = assemblies.Select(path => new RuntimeAssembly(path)).ToArray(); + } + + public IReadOnlyList Assemblies { get; } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.DependencyModel/project.json b/src/Microsoft.Extensions.DependencyModel/project.json index 6b1dc0d9d..e92e75ffa 100644 --- a/src/Microsoft.Extensions.DependencyModel/project.json +++ b/src/Microsoft.Extensions.DependencyModel/project.json @@ -14,10 +14,12 @@ }, "frameworks": { "net451": { }, - "dotnet5.4": { + "dotnet5.5": { "dependencies": { + "System.IO.FileSystem": "4.0.1-rc2-23616", "System.Linq": "4.0.1-rc2-23616", "System.Runtime": "4.0.21-rc2-23616", + "System.Reflection": "4.1.0-rc2-23616", "System.Dynamic.Runtime": "4.0.11-rc2-23616" } }