Revert "Remove DependencyModel dependency"
This reverts commit 4299a4d50b.
This commit is contained in:
parent
b7c90c4a67
commit
12d7093278
|
|
@ -1,45 +0,0 @@
|
||||||
// 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.Linq;
|
|
||||||
using Microsoft.Extensions.DependencyModel.Resolution;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel
|
|
||||||
{
|
|
||||||
internal class CompilationLibrary : Library
|
|
||||||
{
|
|
||||||
public CompilationLibrary(string type,
|
|
||||||
string name,
|
|
||||||
string version,
|
|
||||||
string hash,
|
|
||||||
IEnumerable<string> assemblies,
|
|
||||||
IEnumerable<Dependency> dependencies,
|
|
||||||
bool serviceable)
|
|
||||||
: base(type, name, version, hash, dependencies, serviceable)
|
|
||||||
{
|
|
||||||
Assemblies = assemblies.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IReadOnlyList<string> Assemblies { get; }
|
|
||||||
|
|
||||||
internal static ICompilationAssemblyResolver DefaultResolver { get; } = new CompositeCompilationAssemblyResolver(new ICompilationAssemblyResolver[]
|
|
||||||
{
|
|
||||||
new PackageCacheCompilationAssemblyResolver(),
|
|
||||||
new AppBaseCompilationAssemblyResolver(),
|
|
||||||
new ReferenceAssemblyPathResolver(),
|
|
||||||
new PackageCompilationAssemblyResolver()
|
|
||||||
});
|
|
||||||
|
|
||||||
public IEnumerable<string> ResolveReferencePaths()
|
|
||||||
{
|
|
||||||
var assemblies = new List<string>();
|
|
||||||
if (!DefaultResolver.TryResolveAssemblyPaths(this, assemblies))
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"Can not find compilation library location for package '{Name}'");
|
|
||||||
}
|
|
||||||
return assemblies;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
// 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
|
|
||||||
{
|
|
||||||
internal class CompilationOptions
|
|
||||||
{
|
|
||||||
public IEnumerable<string> Defines { get; }
|
|
||||||
|
|
||||||
public string LanguageVersion { get; }
|
|
||||||
|
|
||||||
public string Platform { get; }
|
|
||||||
|
|
||||||
public bool? AllowUnsafe { get; }
|
|
||||||
|
|
||||||
public bool? WarningsAsErrors { get; }
|
|
||||||
|
|
||||||
public bool? Optimize { get; }
|
|
||||||
|
|
||||||
public string KeyFile { get; }
|
|
||||||
|
|
||||||
public bool? DelaySign { get; }
|
|
||||||
|
|
||||||
public bool? PublicSign { get; }
|
|
||||||
|
|
||||||
public string DebugType { get; }
|
|
||||||
|
|
||||||
public bool? EmitEntryPoint { get; }
|
|
||||||
|
|
||||||
public bool? GenerateXmlDocumentation { get; }
|
|
||||||
|
|
||||||
public static CompilationOptions Default { get; } = new CompilationOptions(
|
|
||||||
defines: Enumerable.Empty<string>(),
|
|
||||||
languageVersion: null,
|
|
||||||
platform: null,
|
|
||||||
allowUnsafe: null,
|
|
||||||
warningsAsErrors: null,
|
|
||||||
optimize: null,
|
|
||||||
keyFile: null,
|
|
||||||
delaySign: null,
|
|
||||||
publicSign: null,
|
|
||||||
debugType: null,
|
|
||||||
emitEntryPoint: null,
|
|
||||||
generateXmlDocumentation: null);
|
|
||||||
|
|
||||||
public CompilationOptions(IEnumerable<string> defines,
|
|
||||||
string languageVersion,
|
|
||||||
string platform,
|
|
||||||
bool? allowUnsafe,
|
|
||||||
bool? warningsAsErrors,
|
|
||||||
bool? optimize,
|
|
||||||
string keyFile,
|
|
||||||
bool? delaySign,
|
|
||||||
bool? publicSign,
|
|
||||||
string debugType,
|
|
||||||
bool? emitEntryPoint,
|
|
||||||
bool? generateXmlDocumentation)
|
|
||||||
{
|
|
||||||
Defines = defines;
|
|
||||||
LanguageVersion = languageVersion;
|
|
||||||
Platform = platform;
|
|
||||||
AllowUnsafe = allowUnsafe;
|
|
||||||
WarningsAsErrors = warningsAsErrors;
|
|
||||||
Optimize = optimize;
|
|
||||||
KeyFile = keyFile;
|
|
||||||
DelaySign = delaySign;
|
|
||||||
PublicSign = publicSign;
|
|
||||||
DebugType = debugType;
|
|
||||||
EmitEntryPoint = emitEntryPoint;
|
|
||||||
GenerateXmlDocumentation = generateXmlDocumentation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
// 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 Microsoft.Extensions.Internal;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel
|
|
||||||
{
|
|
||||||
internal struct Dependency
|
|
||||||
{
|
|
||||||
public Dependency(string name, string version)
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
Version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name { get; }
|
|
||||||
public string Version { get; }
|
|
||||||
|
|
||||||
public bool Equals(Dependency other)
|
|
||||||
{
|
|
||||||
return string.Equals(Name, other.Name) && string.Equals(Version, other.Version);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
if (ReferenceEquals(null, obj)) return false;
|
|
||||||
return obj is Dependency && Equals((Dependency) obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
var combiner = HashCodeCombiner.Start();
|
|
||||||
combiner.Add(Name);
|
|
||||||
combiner.Add(Version);
|
|
||||||
return combiner.CombinedHash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,115 +0,0 @@
|
||||||
// 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.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel
|
|
||||||
{
|
|
||||||
internal class DependencyContext
|
|
||||||
{
|
|
||||||
private static readonly Lazy<DependencyContext> _defaultContext = new Lazy<DependencyContext>(LoadDefault);
|
|
||||||
|
|
||||||
public DependencyContext(string targetFramework,
|
|
||||||
string runtime,
|
|
||||||
bool isPortable,
|
|
||||||
CompilationOptions compilationOptions,
|
|
||||||
IEnumerable<CompilationLibrary> compileLibraries,
|
|
||||||
IEnumerable<RuntimeLibrary> runtimeLibraries,
|
|
||||||
IEnumerable<RuntimeFallbacks> runtimeGraph)
|
|
||||||
{
|
|
||||||
if (targetFramework == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(targetFramework));
|
|
||||||
}
|
|
||||||
if (runtime == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(runtime));
|
|
||||||
}
|
|
||||||
if (compilationOptions == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(compilationOptions));
|
|
||||||
}
|
|
||||||
if (compileLibraries == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(compileLibraries));
|
|
||||||
}
|
|
||||||
if (runtimeLibraries == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(runtimeLibraries));
|
|
||||||
}
|
|
||||||
if (runtimeGraph == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(runtimeGraph));
|
|
||||||
}
|
|
||||||
|
|
||||||
TargetFramework = targetFramework;
|
|
||||||
Runtime = runtime;
|
|
||||||
IsPortable = isPortable;
|
|
||||||
CompilationOptions = compilationOptions;
|
|
||||||
CompileLibraries = compileLibraries.ToArray();
|
|
||||||
RuntimeLibraries = runtimeLibraries.ToArray();
|
|
||||||
RuntimeGraph = runtimeGraph.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DependencyContext Default => _defaultContext.Value;
|
|
||||||
|
|
||||||
public string TargetFramework { get; }
|
|
||||||
|
|
||||||
public string Runtime { get; }
|
|
||||||
|
|
||||||
public bool IsPortable { get; }
|
|
||||||
|
|
||||||
public CompilationOptions CompilationOptions { get; }
|
|
||||||
|
|
||||||
public IReadOnlyList<CompilationLibrary> CompileLibraries { get; }
|
|
||||||
|
|
||||||
public IReadOnlyList<RuntimeLibrary> RuntimeLibraries { get; }
|
|
||||||
|
|
||||||
public IReadOnlyList<RuntimeFallbacks> RuntimeGraph { get; }
|
|
||||||
|
|
||||||
public DependencyContext Merge(DependencyContext other)
|
|
||||||
{
|
|
||||||
if (other == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(other));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DependencyContext(
|
|
||||||
TargetFramework,
|
|
||||||
Runtime,
|
|
||||||
IsPortable,
|
|
||||||
CompilationOptions,
|
|
||||||
CompileLibraries.Union(other.CompileLibraries, new LibraryMergeEqualityComparer<CompilationLibrary>()),
|
|
||||||
RuntimeLibraries.Union(other.RuntimeLibraries, new LibraryMergeEqualityComparer<RuntimeLibrary>()),
|
|
||||||
RuntimeGraph.Union(other.RuntimeGraph)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static DependencyContext LoadDefault()
|
|
||||||
{
|
|
||||||
return DependencyContextLoader.Default.Load(Assembly.GetEntryAssembly());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DependencyContext Load(Assembly assembly)
|
|
||||||
{
|
|
||||||
return DependencyContextLoader.Default.Load(assembly);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class LibraryMergeEqualityComparer<T>: IEqualityComparer<T> where T:Library
|
|
||||||
{
|
|
||||||
public bool Equals(T x, T y)
|
|
||||||
{
|
|
||||||
return string.Equals(x.Name, y.Name, StringComparison.Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetHashCode(T obj)
|
|
||||||
{
|
|
||||||
return obj.Name.GetHashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,135 +0,0 @@
|
||||||
// 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.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel
|
|
||||||
{
|
|
||||||
internal class DependencyContextCsvReader: IDependencyContextReader
|
|
||||||
{
|
|
||||||
public DependencyContext Read(Stream stream)
|
|
||||||
{
|
|
||||||
var lines = new List<DepsFileLine>();
|
|
||||||
using (var reader = new StreamReader(stream))
|
|
||||||
{
|
|
||||||
while (!reader.EndOfStream)
|
|
||||||
{
|
|
||||||
var line = new DepsFileLine();
|
|
||||||
line.LibraryType = ReadValue(reader);
|
|
||||||
line.PackageName = ReadValue(reader);
|
|
||||||
line.PackageVersion = ReadValue(reader);
|
|
||||||
line.PackageHash = ReadValue(reader);
|
|
||||||
line.AssetType = ReadValue(reader);
|
|
||||||
line.AssetName = ReadValue(reader);
|
|
||||||
line.AssetPath = ReadValue(reader);
|
|
||||||
|
|
||||||
if (line.AssetType == "runtime" &&
|
|
||||||
!line.AssetPath.EndsWith(".ni.dll"))
|
|
||||||
{
|
|
||||||
lines.Add(line);
|
|
||||||
}
|
|
||||||
SkipWhitespace(reader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var runtimeLibraries = new List<RuntimeLibrary>();
|
|
||||||
var packageGroups = lines.GroupBy(PackageIdentity);
|
|
||||||
foreach (var packageGroup in packageGroups)
|
|
||||||
{
|
|
||||||
var identity = packageGroup.Key;
|
|
||||||
runtimeLibraries.Add(new RuntimeLibrary(
|
|
||||||
type: identity.Item1,
|
|
||||||
name: identity.Item2,
|
|
||||||
version: identity.Item3,
|
|
||||||
hash: identity.Item4,
|
|
||||||
assemblies: packageGroup.Select(l => RuntimeAssembly.Create(l.AssetPath)),
|
|
||||||
nativeLibraries: Enumerable.Empty<string>(),
|
|
||||||
resourceAssemblies: Enumerable.Empty<ResourceAssembly>(),
|
|
||||||
subTargets: Enumerable.Empty<RuntimeTarget>(),
|
|
||||||
dependencies: Enumerable.Empty<Dependency>(),
|
|
||||||
serviceable: false
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DependencyContext(
|
|
||||||
targetFramework: string.Empty,
|
|
||||||
runtime: string.Empty,
|
|
||||||
isPortable: false,
|
|
||||||
compilationOptions: CompilationOptions.Default,
|
|
||||||
compileLibraries: Enumerable.Empty<CompilationLibrary>(),
|
|
||||||
runtimeLibraries: runtimeLibraries.ToArray(),
|
|
||||||
runtimeGraph: Enumerable.Empty<RuntimeFallbacks>());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Tuple<string, string, string, string> PackageIdentity(DepsFileLine line)
|
|
||||||
{
|
|
||||||
return Tuple.Create(line.LibraryType, line.PackageName, line.PackageVersion, line.PackageHash);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SkipWhitespace(StreamReader reader)
|
|
||||||
{
|
|
||||||
// skip all whitespace
|
|
||||||
while (!reader.EndOfStream && char.IsWhiteSpace((char)reader.Peek()))
|
|
||||||
{
|
|
||||||
reader.Read();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string ReadValue(StreamReader reader)
|
|
||||||
{
|
|
||||||
SkipWhitespace(reader);
|
|
||||||
|
|
||||||
var c = ReadSucceed(reader.Read());
|
|
||||||
if (c != '"')
|
|
||||||
{
|
|
||||||
throw new FormatException("Deps file value should start with '\"'");
|
|
||||||
}
|
|
||||||
|
|
||||||
var value = new StringBuilder();
|
|
||||||
while (ReadSucceed(reader.Peek()) != '"')
|
|
||||||
{
|
|
||||||
c = ReadSucceed(reader.Read());
|
|
||||||
if (c == '\\')
|
|
||||||
{
|
|
||||||
value.Append(ReadSucceed(reader.Read()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value.Append(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Read last "
|
|
||||||
ReadSucceed(reader.Read());
|
|
||||||
// Read comment
|
|
||||||
if (reader.Peek() == ',')
|
|
||||||
{
|
|
||||||
reader.Read();
|
|
||||||
}
|
|
||||||
return value.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private char ReadSucceed(int c)
|
|
||||||
{
|
|
||||||
if (c == -1)
|
|
||||||
{
|
|
||||||
throw new FormatException("Unexpected end of file");
|
|
||||||
}
|
|
||||||
return (char) c;
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct DepsFileLine
|
|
||||||
{
|
|
||||||
public string LibraryType;
|
|
||||||
public string PackageName;
|
|
||||||
public string PackageVersion;
|
|
||||||
public string PackageHash;
|
|
||||||
public string AssetType;
|
|
||||||
public string AssetName;
|
|
||||||
public string AssetPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,294 +0,0 @@
|
||||||
// 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.Linq;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel
|
|
||||||
{
|
|
||||||
internal class DependencyContextJsonReader: IDependencyContextReader
|
|
||||||
{
|
|
||||||
public DependencyContext Read(Stream stream)
|
|
||||||
{
|
|
||||||
using (var streamReader = new StreamReader(stream))
|
|
||||||
{
|
|
||||||
using (var reader = new JsonTextReader(streamReader))
|
|
||||||
{
|
|
||||||
var root = JObject.Load(reader);
|
|
||||||
return Read(root);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsRuntimeTarget(string name) => name.Contains(DependencyContextStrings.VersionSeperator);
|
|
||||||
|
|
||||||
private DependencyContext Read(JObject root)
|
|
||||||
{
|
|
||||||
var runtime = string.Empty;
|
|
||||||
var target = string.Empty;
|
|
||||||
var isPortable = true;
|
|
||||||
|
|
||||||
var runtimeTargetName = root[DependencyContextStrings.RuntimeTargetPropertyName]?.Value<string>();
|
|
||||||
|
|
||||||
var libraryStubs = ReadLibraryStubs((JObject) root[DependencyContextStrings.LibrariesPropertyName]);
|
|
||||||
var targetsObject = (JObject) root[DependencyContextStrings.TargetsPropertyName];
|
|
||||||
|
|
||||||
JObject runtimeTarget = null;
|
|
||||||
JObject compileTarget = null;
|
|
||||||
if (targetsObject != null)
|
|
||||||
{
|
|
||||||
var compileTargetProperty = targetsObject.Properties()
|
|
||||||
.FirstOrDefault(p => !IsRuntimeTarget(p.Name));
|
|
||||||
|
|
||||||
compileTarget = (JObject)compileTargetProperty.Value;
|
|
||||||
target = compileTargetProperty.Name;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(runtimeTargetName))
|
|
||||||
{
|
|
||||||
runtimeTarget = (JObject) targetsObject[runtimeTargetName];
|
|
||||||
if (runtimeTarget == null)
|
|
||||||
{
|
|
||||||
throw new FormatException($"Target with name {runtimeTargetName} not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
var seperatorIndex = runtimeTargetName.IndexOf(DependencyContextStrings.VersionSeperator);
|
|
||||||
if (seperatorIndex > -1 && seperatorIndex < runtimeTargetName.Length)
|
|
||||||
{
|
|
||||||
runtime = runtimeTargetName.Substring(seperatorIndex + 1);
|
|
||||||
isPortable = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
runtimeTarget = compileTarget;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DependencyContext(
|
|
||||||
target,
|
|
||||||
runtime,
|
|
||||||
isPortable,
|
|
||||||
ReadCompilationOptions((JObject)root[DependencyContextStrings.CompilationOptionsPropertName]),
|
|
||||||
ReadLibraries(compileTarget, false, libraryStubs).Cast<CompilationLibrary>().ToArray(),
|
|
||||||
ReadLibraries(runtimeTarget, true, libraryStubs).Cast<RuntimeLibrary>().ToArray(),
|
|
||||||
ReadRuntimeGraph((JObject)root[DependencyContextStrings.RuntimesPropertyName]).ToArray()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<RuntimeFallbacks> ReadRuntimeGraph(JObject runtimes)
|
|
||||||
{
|
|
||||||
if (runtimes == null)
|
|
||||||
{
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var pair in runtimes)
|
|
||||||
{
|
|
||||||
yield return new RuntimeFallbacks(pair.Key, pair.Value.Values<string>().ToArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private CompilationOptions ReadCompilationOptions(JObject compilationOptionsObject)
|
|
||||||
{
|
|
||||||
if (compilationOptionsObject == null)
|
|
||||||
{
|
|
||||||
return CompilationOptions.Default;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new CompilationOptions(
|
|
||||||
compilationOptionsObject[DependencyContextStrings.DefinesPropertyName]?.Values<string>(),
|
|
||||||
compilationOptionsObject[DependencyContextStrings.LanguageVersionPropertyName]?.Value<string>(),
|
|
||||||
compilationOptionsObject[DependencyContextStrings.PlatformPropertyName]?.Value<string>(),
|
|
||||||
compilationOptionsObject[DependencyContextStrings.AllowUnsafePropertyName]?.Value<bool>(),
|
|
||||||
compilationOptionsObject[DependencyContextStrings.WarningsAsErrorsPropertyName]?.Value<bool>(),
|
|
||||||
compilationOptionsObject[DependencyContextStrings.OptimizePropertyName]?.Value<bool>(),
|
|
||||||
compilationOptionsObject[DependencyContextStrings.KeyFilePropertyName]?.Value<string>(),
|
|
||||||
compilationOptionsObject[DependencyContextStrings.DelaySignPropertyName]?.Value<bool>(),
|
|
||||||
compilationOptionsObject[DependencyContextStrings.PublicSignPropertyName]?.Value<bool>(),
|
|
||||||
compilationOptionsObject[DependencyContextStrings.DebugTypePropertyName]?.Value<string>(),
|
|
||||||
compilationOptionsObject[DependencyContextStrings.EmitEntryPointPropertyName]?.Value<bool>(),
|
|
||||||
compilationOptionsObject[DependencyContextStrings.GenerateXmlDocumentationPropertyName]?.Value<bool>()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<Library> ReadLibraries(JObject librariesObject, bool runtime, Dictionary<string, LibraryStub> libraryStubs)
|
|
||||||
{
|
|
||||||
if (librariesObject == null)
|
|
||||||
{
|
|
||||||
return Enumerable.Empty<Library>();
|
|
||||||
}
|
|
||||||
return librariesObject.Properties().Select(property => ReadLibrary(property, runtime, libraryStubs));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Library ReadLibrary(JProperty property, bool runtime, Dictionary<string, LibraryStub> libraryStubs)
|
|
||||||
{
|
|
||||||
var nameWithVersion = property.Name;
|
|
||||||
LibraryStub stub;
|
|
||||||
|
|
||||||
if (!libraryStubs.TryGetValue(nameWithVersion, out stub))
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"Cannot find library information for {nameWithVersion}");
|
|
||||||
}
|
|
||||||
|
|
||||||
var seperatorPosition = nameWithVersion.IndexOf(DependencyContextStrings.VersionSeperator);
|
|
||||||
|
|
||||||
var name = nameWithVersion.Substring(0, seperatorPosition);
|
|
||||||
var version = nameWithVersion.Substring(seperatorPosition + 1);
|
|
||||||
|
|
||||||
var libraryObject = (JObject) property.Value;
|
|
||||||
|
|
||||||
var dependencies = ReadDependencies(libraryObject);
|
|
||||||
|
|
||||||
if (runtime)
|
|
||||||
{
|
|
||||||
var runtimeTargets = new List<RuntimeTarget>();
|
|
||||||
var runtimeTargetsObject = (JObject)libraryObject[DependencyContextStrings.RuntimeTargetsPropertyName];
|
|
||||||
|
|
||||||
var entries = ReadRuntimeTargetEntries(runtimeTargetsObject).ToArray();
|
|
||||||
|
|
||||||
foreach (var ridGroup in entries.GroupBy(e => e.Rid))
|
|
||||||
{
|
|
||||||
var runtimeAssets = entries.Where(e => e.Type == DependencyContextStrings.RuntimeAssetType)
|
|
||||||
.Select(e => RuntimeAssembly.Create(e.Path))
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
var nativeAssets = entries.Where(e => e.Type == DependencyContextStrings.NativeAssetType)
|
|
||||||
.Select(e => e.Path)
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
runtimeTargets.Add(new RuntimeTarget(
|
|
||||||
ridGroup.Key,
|
|
||||||
runtimeAssets,
|
|
||||||
nativeAssets
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
var assemblies = ReadAssetList(libraryObject, DependencyContextStrings.RuntimeAssembliesKey)
|
|
||||||
.Select(RuntimeAssembly.Create)
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
var nativeLibraries = ReadAssetList(libraryObject, DependencyContextStrings.NativeLibrariesKey);
|
|
||||||
|
|
||||||
var resourceAssemblies = ReadResourceAssemblies((JObject)libraryObject[DependencyContextStrings.ResourceAssembliesPropertyName]);
|
|
||||||
|
|
||||||
return new RuntimeLibrary(
|
|
||||||
type: stub.Type,
|
|
||||||
name: name,
|
|
||||||
version: version,
|
|
||||||
hash: stub.Hash,
|
|
||||||
assemblies: assemblies,
|
|
||||||
nativeLibraries: nativeLibraries,
|
|
||||||
resourceAssemblies: resourceAssemblies,
|
|
||||||
subTargets: runtimeTargets.ToArray(),
|
|
||||||
dependencies: dependencies,
|
|
||||||
serviceable: stub.Serviceable);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var assemblies = ReadAssetList(libraryObject, DependencyContextStrings.CompileTimeAssembliesKey);
|
|
||||||
return new CompilationLibrary(stub.Type, name, version, stub.Hash, assemblies, dependencies, stub.Serviceable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<ResourceAssembly> ReadResourceAssemblies(JObject resourcesObject)
|
|
||||||
{
|
|
||||||
if (resourcesObject == null)
|
|
||||||
{
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
foreach (var resourceProperty in resourcesObject)
|
|
||||||
{
|
|
||||||
yield return new ResourceAssembly(
|
|
||||||
locale: resourceProperty.Value[DependencyContextStrings.LocalePropertyName]?.Value<string>(),
|
|
||||||
path: resourceProperty.Key
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<RuntimeTargetEntryStub> ReadRuntimeTargetEntries(JObject runtimeTargetObject)
|
|
||||||
{
|
|
||||||
if (runtimeTargetObject == null)
|
|
||||||
{
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
foreach (var libraryProperty in runtimeTargetObject)
|
|
||||||
{
|
|
||||||
var libraryObject = (JObject)libraryProperty.Value;
|
|
||||||
yield return new RuntimeTargetEntryStub()
|
|
||||||
{
|
|
||||||
Path = libraryProperty.Key,
|
|
||||||
Rid = libraryObject[DependencyContextStrings.RidPropertyName].Value<string>(),
|
|
||||||
Type = libraryObject[DependencyContextStrings.AssetTypePropertyName].Value<string>()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string[] ReadAssetList(JObject libraryObject, string name)
|
|
||||||
{
|
|
||||||
var assembliesObject = (JObject) libraryObject[name];
|
|
||||||
|
|
||||||
if (assembliesObject == null)
|
|
||||||
{
|
|
||||||
return new string[] {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return assembliesObject.Properties().Select(property => property.Name).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Dependency[] ReadDependencies(JObject libraryObject)
|
|
||||||
{
|
|
||||||
var dependenciesObject = (JObject) libraryObject[DependencyContextStrings.DependenciesPropertyName];
|
|
||||||
|
|
||||||
if (dependenciesObject == null)
|
|
||||||
{
|
|
||||||
return new Dependency[]{ };
|
|
||||||
}
|
|
||||||
|
|
||||||
return dependenciesObject.Properties()
|
|
||||||
.Select(property => new Dependency(property.Name, (string) property.Value)).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dictionary<string, LibraryStub> ReadLibraryStubs(JObject librariesObject)
|
|
||||||
{
|
|
||||||
var libraries = new Dictionary<string, LibraryStub>();
|
|
||||||
if (librariesObject != null)
|
|
||||||
{
|
|
||||||
foreach (var libraryProperty in librariesObject)
|
|
||||||
{
|
|
||||||
var value = (JObject) libraryProperty.Value;
|
|
||||||
var stub = new LibraryStub
|
|
||||||
{
|
|
||||||
Name = libraryProperty.Key,
|
|
||||||
Hash = value[DependencyContextStrings.Sha512PropertyName]?.Value<string>(),
|
|
||||||
Type = value[DependencyContextStrings.TypePropertyName].Value<string>(),
|
|
||||||
Serviceable = value[DependencyContextStrings.ServiceablePropertyName]?.Value<bool>() == true
|
|
||||||
};
|
|
||||||
libraries.Add(stub.Name, stub);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return libraries;
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct RuntimeTargetEntryStub
|
|
||||||
{
|
|
||||||
public string Type;
|
|
||||||
public string Path;
|
|
||||||
public string Rid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct LibraryStub
|
|
||||||
{
|
|
||||||
public string Name;
|
|
||||||
|
|
||||||
public string Hash;
|
|
||||||
|
|
||||||
public string Type;
|
|
||||||
|
|
||||||
public bool Serviceable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,170 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel
|
|
||||||
{
|
|
||||||
internal class DependencyContextLoader
|
|
||||||
{
|
|
||||||
private static Lazy<string[]> _depsFiles = new Lazy<string[]>(GetHostDepsList);
|
|
||||||
|
|
||||||
private const string DepsJsonExtension = ".deps.json";
|
|
||||||
private const string DepsExtension = ".deps";
|
|
||||||
|
|
||||||
private readonly string _entryPointDepsLocation;
|
|
||||||
private readonly string _runtimeDepsLocation;
|
|
||||||
private readonly IDependencyContextReader _jsonReader;
|
|
||||||
private readonly IDependencyContextReader _csvReader;
|
|
||||||
|
|
||||||
public DependencyContextLoader() : this(
|
|
||||||
GetDefaultEntrypointDepsLocation(),
|
|
||||||
GetDefaultRuntimeDepsLocation(),
|
|
||||||
new DependencyContextJsonReader(),
|
|
||||||
new DependencyContextCsvReader())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
internal DependencyContextLoader(
|
|
||||||
string entryPointDepsLocation,
|
|
||||||
string runtimeDepsLocation,
|
|
||||||
IDependencyContextReader jsonReader,
|
|
||||||
IDependencyContextReader csvReader)
|
|
||||||
{
|
|
||||||
_entryPointDepsLocation = entryPointDepsLocation;
|
|
||||||
_runtimeDepsLocation = runtimeDepsLocation;
|
|
||||||
_jsonReader = jsonReader;
|
|
||||||
_csvReader = csvReader;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DependencyContextLoader Default { get; } = new DependencyContextLoader();
|
|
||||||
|
|
||||||
internal virtual bool IsEntryAssembly(Assembly assembly)
|
|
||||||
{
|
|
||||||
return assembly.GetName() == Assembly.GetEntryAssembly()?.GetName();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal virtual Stream GetResourceStream(Assembly assembly, string name)
|
|
||||||
{
|
|
||||||
return assembly.GetManifestResourceStream(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DependencyContext Load(Assembly assembly)
|
|
||||||
{
|
|
||||||
if (assembly == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(assembly));
|
|
||||||
}
|
|
||||||
|
|
||||||
DependencyContext context = null;
|
|
||||||
|
|
||||||
if (IsEntryAssembly(assembly))
|
|
||||||
{
|
|
||||||
context = LoadEntryAssemblyContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context == null)
|
|
||||||
{
|
|
||||||
context = LoadAssemblyContext(assembly);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context?.IsPortable == true)
|
|
||||||
{
|
|
||||||
var runtimeContext = LoadRuntimeContext();
|
|
||||||
if (runtimeContext != null)
|
|
||||||
{
|
|
||||||
context = context.Merge(runtimeContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DependencyContext LoadEntryAssemblyContext()
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(_entryPointDepsLocation))
|
|
||||||
{
|
|
||||||
Debug.Assert(File.Exists(_entryPointDepsLocation));
|
|
||||||
using (var stream = File.OpenRead(_entryPointDepsLocation))
|
|
||||||
{
|
|
||||||
return _jsonReader.Read(stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DependencyContext LoadRuntimeContext()
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(_runtimeDepsLocation))
|
|
||||||
{
|
|
||||||
Debug.Assert(File.Exists(_runtimeDepsLocation));
|
|
||||||
using (var stream = File.OpenRead(_runtimeDepsLocation))
|
|
||||||
{
|
|
||||||
return _jsonReader.Read(stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DependencyContext LoadAssemblyContext(Assembly assembly)
|
|
||||||
{
|
|
||||||
using (var stream = GetResourceStream(assembly, assembly.GetName().Name + DepsJsonExtension))
|
|
||||||
{
|
|
||||||
if (stream != null)
|
|
||||||
{
|
|
||||||
return _jsonReader.Read(stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var depsJsonFile = Path.ChangeExtension(assembly.Location, DepsJsonExtension);
|
|
||||||
if (File.Exists(depsJsonFile))
|
|
||||||
{
|
|
||||||
using (var stream = File.OpenRead(depsJsonFile))
|
|
||||||
{
|
|
||||||
return _jsonReader.Read(stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var depsFile = Path.ChangeExtension(assembly.Location, DepsExtension);
|
|
||||||
if (File.Exists(depsFile))
|
|
||||||
{
|
|
||||||
using (var stream = File.OpenRead(depsFile))
|
|
||||||
{
|
|
||||||
return _csvReader.Read(stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetDefaultRuntimeDepsLocation()
|
|
||||||
{
|
|
||||||
var deps = _depsFiles.Value;
|
|
||||||
if (deps != null && deps.Length > 1)
|
|
||||||
{
|
|
||||||
return deps[1];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetDefaultEntrypointDepsLocation()
|
|
||||||
{
|
|
||||||
var deps = _depsFiles.Value;
|
|
||||||
if (deps != null && deps.Length > 0)
|
|
||||||
{
|
|
||||||
return deps[0];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string[] GetHostDepsList()
|
|
||||||
{
|
|
||||||
// TODO: Were going to replace this with AppContext.GetData
|
|
||||||
var appDomainType = typeof(object).GetTypeInfo().Assembly?.GetType("System.AppDomain");
|
|
||||||
var currentDomain = appDomainType?.GetProperty("CurrentDomain")?.GetValue(null);
|
|
||||||
var deps = appDomainType?.GetMethod("GetData")?.Invoke(currentDomain, new[] { "APP_CONTEXT_DEPS_FILES" });
|
|
||||||
|
|
||||||
return (deps as string)?.Split(new [] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
// 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
|
|
||||||
{
|
|
||||||
internal const char VersionSeperator = '/';
|
|
||||||
|
|
||||||
internal const string CompileTimeAssembliesKey = "compile";
|
|
||||||
|
|
||||||
internal const string RuntimeAssembliesKey = "runtime";
|
|
||||||
|
|
||||||
internal const string NativeLibrariesKey = "native";
|
|
||||||
|
|
||||||
internal const string RuntimeTargetPropertyName = "runtimeTarget";
|
|
||||||
|
|
||||||
internal const string LibrariesPropertyName = "libraries";
|
|
||||||
|
|
||||||
internal const string TargetsPropertyName = "targets";
|
|
||||||
|
|
||||||
internal const string DependenciesPropertyName = "dependencies";
|
|
||||||
|
|
||||||
internal const string Sha512PropertyName = "sha512";
|
|
||||||
|
|
||||||
internal const string TypePropertyName = "type";
|
|
||||||
|
|
||||||
internal const string ServiceablePropertyName = "serviceable";
|
|
||||||
|
|
||||||
internal const string CompilationOptionsPropertName = "compilationOptions";
|
|
||||||
|
|
||||||
internal const string DefinesPropertyName = "defines";
|
|
||||||
|
|
||||||
internal const string LanguageVersionPropertyName = "languageVersion";
|
|
||||||
|
|
||||||
internal const string PlatformPropertyName = "platform";
|
|
||||||
|
|
||||||
internal const string AllowUnsafePropertyName = "allowUnsafe";
|
|
||||||
|
|
||||||
internal const string WarningsAsErrorsPropertyName = "warningsAsErrors";
|
|
||||||
|
|
||||||
internal const string OptimizePropertyName = "optimize";
|
|
||||||
|
|
||||||
internal const string KeyFilePropertyName = "keyFile";
|
|
||||||
|
|
||||||
internal const string DelaySignPropertyName = "delaySign";
|
|
||||||
|
|
||||||
internal const string PublicSignPropertyName = "publicSign";
|
|
||||||
|
|
||||||
internal const string DebugTypePropertyName = "debugType";
|
|
||||||
|
|
||||||
internal const string EmitEntryPointPropertyName = "emitEntryPoint";
|
|
||||||
|
|
||||||
internal const string GenerateXmlDocumentationPropertyName = "xmlDoc";
|
|
||||||
|
|
||||||
internal const string PortablePropertyName = "portable";
|
|
||||||
|
|
||||||
internal const string RuntimeTargetNamePropertyName = "name";
|
|
||||||
|
|
||||||
internal const string RuntimesPropertyName = "runtimes";
|
|
||||||
|
|
||||||
internal const string RuntimeTargetsPropertyName = "runtimeTargets";
|
|
||||||
|
|
||||||
internal const string RidPropertyName = "rid";
|
|
||||||
|
|
||||||
internal const string AssetTypePropertyName = "assetType";
|
|
||||||
|
|
||||||
internal const string RuntimeAssetType = "runtime";
|
|
||||||
|
|
||||||
internal const string NativeAssetType = "native";
|
|
||||||
|
|
||||||
internal const string ResourceAssembliesPropertyName = "resources";
|
|
||||||
|
|
||||||
internal const string LocalePropertyName = "locale";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,309 +0,0 @@
|
||||||
// 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.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.Extensions.PlatformAbstractions;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel
|
|
||||||
{
|
|
||||||
internal class DependencyContextWriter
|
|
||||||
{
|
|
||||||
public void Write(DependencyContext context, Stream stream)
|
|
||||||
{
|
|
||||||
using (var writer = new StreamWriter(stream))
|
|
||||||
{
|
|
||||||
using (var jsonWriter = new JsonTextWriter(writer) { Formatting = Formatting.Indented })
|
|
||||||
{
|
|
||||||
Write(context).WriteTo(jsonWriter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private JObject Write(DependencyContext context)
|
|
||||||
{
|
|
||||||
var contextObject = new JObject(
|
|
||||||
new JProperty(DependencyContextStrings.RuntimeTargetPropertyName, WriteRuntimeTargetInfo(context)),
|
|
||||||
new JProperty(DependencyContextStrings.CompilationOptionsPropertName, WriteCompilationOptions(context.CompilationOptions)),
|
|
||||||
new JProperty(DependencyContextStrings.TargetsPropertyName, WriteTargets(context)),
|
|
||||||
new JProperty(DependencyContextStrings.LibrariesPropertyName, WriteLibraries(context))
|
|
||||||
);
|
|
||||||
if (context.RuntimeGraph.Any())
|
|
||||||
{
|
|
||||||
contextObject.Add(new JProperty(DependencyContextStrings.RuntimesPropertyName, WriteRuntimeGraph(context)));
|
|
||||||
}
|
|
||||||
return contextObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string WriteRuntimeTargetInfo(DependencyContext context)
|
|
||||||
{
|
|
||||||
return context.IsPortable?
|
|
||||||
context.TargetFramework :
|
|
||||||
context.TargetFramework + DependencyContextStrings.VersionSeperator + context.Runtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
private JObject WriteRuntimeGraph(DependencyContext context)
|
|
||||||
{
|
|
||||||
return new JObject(
|
|
||||||
context.RuntimeGraph.Select(g => new JProperty(g.Runtime, new JArray(g.Fallbacks)))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private JObject WriteCompilationOptions(CompilationOptions compilationOptions)
|
|
||||||
{
|
|
||||||
var o = new JObject();
|
|
||||||
if (compilationOptions.Defines?.Any() == true)
|
|
||||||
{
|
|
||||||
o[DependencyContextStrings.DefinesPropertyName] = new JArray(compilationOptions.Defines);
|
|
||||||
}
|
|
||||||
AddPropertyIfNotNull(o, DependencyContextStrings.LanguageVersionPropertyName, compilationOptions.LanguageVersion);
|
|
||||||
AddPropertyIfNotNull(o, DependencyContextStrings.PlatformPropertyName, compilationOptions.Platform);
|
|
||||||
AddPropertyIfNotNull(o, DependencyContextStrings.AllowUnsafePropertyName, compilationOptions.AllowUnsafe);
|
|
||||||
AddPropertyIfNotNull(o, DependencyContextStrings.WarningsAsErrorsPropertyName, compilationOptions.WarningsAsErrors);
|
|
||||||
AddPropertyIfNotNull(o, DependencyContextStrings.OptimizePropertyName, compilationOptions.Optimize);
|
|
||||||
AddPropertyIfNotNull(o, DependencyContextStrings.KeyFilePropertyName, compilationOptions.KeyFile);
|
|
||||||
AddPropertyIfNotNull(o, DependencyContextStrings.DelaySignPropertyName, compilationOptions.DelaySign);
|
|
||||||
AddPropertyIfNotNull(o, DependencyContextStrings.PublicSignPropertyName, compilationOptions.PublicSign);
|
|
||||||
AddPropertyIfNotNull(o, DependencyContextStrings.EmitEntryPointPropertyName, compilationOptions.EmitEntryPoint);
|
|
||||||
AddPropertyIfNotNull(o, DependencyContextStrings.GenerateXmlDocumentationPropertyName, compilationOptions.GenerateXmlDocumentation);
|
|
||||||
AddPropertyIfNotNull(o, DependencyContextStrings.DebugTypePropertyName, compilationOptions.DebugType);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddPropertyIfNotNull<T>(JObject o, string name, T value)
|
|
||||||
{
|
|
||||||
if (value != null)
|
|
||||||
{
|
|
||||||
o.Add(new JProperty(name, value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private JObject WriteTargets(DependencyContext context)
|
|
||||||
{
|
|
||||||
if (context.IsPortable)
|
|
||||||
{
|
|
||||||
return new JObject(
|
|
||||||
new JProperty(context.TargetFramework, WritePortableTarget(context.RuntimeLibraries, context.CompileLibraries))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new JObject(
|
|
||||||
new JProperty(context.TargetFramework, WriteTarget(context.CompileLibraries)),
|
|
||||||
new JProperty(context.TargetFramework + DependencyContextStrings.VersionSeperator + context.Runtime,
|
|
||||||
WriteTarget(context.RuntimeLibraries))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private JObject WriteTarget(IReadOnlyList<Library> libraries)
|
|
||||||
{
|
|
||||||
return new JObject(
|
|
||||||
libraries.Select(library =>
|
|
||||||
new JProperty(library.Name + DependencyContextStrings.VersionSeperator + library.Version, WriteTargetLibrary(library))));
|
|
||||||
}
|
|
||||||
|
|
||||||
private JObject WritePortableTarget(IReadOnlyList<RuntimeLibrary> runtimeLibraries, IReadOnlyList<CompilationLibrary> compilationLibraries)
|
|
||||||
{
|
|
||||||
var runtimeLookup = runtimeLibraries.ToDictionary(l => l.Name);
|
|
||||||
var compileLookup = compilationLibraries.ToDictionary(l => l.Name);
|
|
||||||
|
|
||||||
var targetObject = new JObject();
|
|
||||||
|
|
||||||
foreach (var packageName in runtimeLookup.Keys.Concat(compileLookup.Keys).Distinct())
|
|
||||||
{
|
|
||||||
RuntimeLibrary runtimeLibrary;
|
|
||||||
runtimeLookup.TryGetValue(packageName, out runtimeLibrary);
|
|
||||||
|
|
||||||
CompilationLibrary compilationLibrary;
|
|
||||||
compileLookup.TryGetValue(packageName, out compilationLibrary);
|
|
||||||
|
|
||||||
if (compilationLibrary != null && runtimeLibrary != null)
|
|
||||||
{
|
|
||||||
Debug.Assert(compilationLibrary.Serviceable == runtimeLibrary.Serviceable);
|
|
||||||
Debug.Assert(compilationLibrary.Version == runtimeLibrary.Version);
|
|
||||||
Debug.Assert(compilationLibrary.Hash == runtimeLibrary.Hash);
|
|
||||||
Debug.Assert(compilationLibrary.Type == runtimeLibrary.Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
var library = (Library)compilationLibrary ?? (Library)runtimeLibrary;
|
|
||||||
targetObject.Add(
|
|
||||||
new JProperty(library.Name + DependencyContextStrings.VersionSeperator + library.Version,
|
|
||||||
WritePortableTargetLibrary(runtimeLibrary, compilationLibrary)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
return targetObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddCompilationAssemblies(JObject libraryObject, IEnumerable<string> compilationAssemblies)
|
|
||||||
{
|
|
||||||
if (!compilationAssemblies.Any())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
libraryObject.Add(new JProperty(DependencyContextStrings.CompileTimeAssembliesKey,
|
|
||||||
WriteAssetList(compilationAssemblies))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddRuntimeAssemblies(JObject libraryObject, IEnumerable<RuntimeAssembly> runtimeAssemblies)
|
|
||||||
{
|
|
||||||
if (!runtimeAssemblies.Any())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
libraryObject.Add(new JProperty(DependencyContextStrings.RuntimeAssembliesKey,
|
|
||||||
WriteAssetList(runtimeAssemblies.Select(a => a.Path)))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddDependencies(JObject libraryObject, IEnumerable<Dependency> dependencies)
|
|
||||||
{
|
|
||||||
if (!dependencies.Any())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
libraryObject.AddFirst(
|
|
||||||
new JProperty(DependencyContextStrings.DependenciesPropertyName,
|
|
||||||
new JObject(
|
|
||||||
dependencies.Select(dependency => new JProperty(dependency.Name, dependency.Version))))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddResourceAssemblies(JObject libraryObject, IEnumerable<ResourceAssembly> resourceAssemblies)
|
|
||||||
{
|
|
||||||
if (!resourceAssemblies.Any())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
libraryObject.Add(DependencyContextStrings.ResourceAssembliesPropertyName,
|
|
||||||
new JObject(resourceAssemblies.Select(a =>
|
|
||||||
new JProperty(NormalizePath(a.Path), new JObject(new JProperty(DependencyContextStrings.LocalePropertyName, a.Locale))))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private JObject WriteTargetLibrary(Library library)
|
|
||||||
{
|
|
||||||
var runtimeLibrary = library as RuntimeLibrary;
|
|
||||||
if (runtimeLibrary != null)
|
|
||||||
{
|
|
||||||
var libraryObject = new JObject();
|
|
||||||
AddDependencies(libraryObject, runtimeLibrary.Dependencies);
|
|
||||||
AddRuntimeAssemblies(libraryObject, runtimeLibrary.Assemblies);
|
|
||||||
AddResourceAssemblies(libraryObject, runtimeLibrary.ResourceAssemblies);
|
|
||||||
|
|
||||||
if (runtimeLibrary.NativeLibraries.Any())
|
|
||||||
{
|
|
||||||
libraryObject.Add(DependencyContextStrings.NativeLibrariesKey, WriteAssetList(runtimeLibrary.NativeLibraries));
|
|
||||||
}
|
|
||||||
|
|
||||||
return libraryObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
var compilationLibrary = library as CompilationLibrary;
|
|
||||||
if (compilationLibrary != null)
|
|
||||||
{
|
|
||||||
var libraryObject = new JObject();
|
|
||||||
AddDependencies(libraryObject, compilationLibrary.Dependencies);
|
|
||||||
AddCompilationAssemblies(libraryObject, compilationLibrary.Assemblies);
|
|
||||||
return libraryObject;
|
|
||||||
}
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
private JObject WritePortableTargetLibrary(RuntimeLibrary runtimeLibrary, CompilationLibrary compilationLibrary)
|
|
||||||
{
|
|
||||||
var libraryObject = new JObject();
|
|
||||||
|
|
||||||
var dependencies = new HashSet<Dependency>();
|
|
||||||
if (runtimeLibrary != null)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (runtimeLibrary.RuntimeTargets.Any())
|
|
||||||
{
|
|
||||||
libraryObject.Add(new JProperty(
|
|
||||||
DependencyContextStrings.RuntimeTargetsPropertyName,
|
|
||||||
new JObject(runtimeLibrary.RuntimeTargets.SelectMany(WriteRuntimeTarget)))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
AddRuntimeAssemblies(libraryObject, runtimeLibrary.Assemblies);
|
|
||||||
AddResourceAssemblies(libraryObject, runtimeLibrary.ResourceAssemblies);
|
|
||||||
libraryObject.Add(DependencyContextStrings.NativeLibrariesKey, WriteAssetList(runtimeLibrary.NativeLibraries));
|
|
||||||
|
|
||||||
dependencies.UnionWith(runtimeLibrary.Dependencies);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (compilationLibrary != null)
|
|
||||||
{
|
|
||||||
AddCompilationAssemblies(libraryObject, compilationLibrary.Assemblies);
|
|
||||||
|
|
||||||
dependencies.UnionWith(compilationLibrary.Dependencies);
|
|
||||||
}
|
|
||||||
|
|
||||||
AddDependencies(libraryObject, dependencies);
|
|
||||||
return libraryObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<JProperty> WriteRuntimeTarget(RuntimeTarget target)
|
|
||||||
{
|
|
||||||
var runtime = WriteRuntimeTargetAssemblies(
|
|
||||||
target.Assemblies.Select(a => a.Path),
|
|
||||||
target.Runtime,
|
|
||||||
DependencyContextStrings.RuntimeAssetType);
|
|
||||||
|
|
||||||
var native = WriteRuntimeTargetAssemblies(
|
|
||||||
target.NativeLibraries,
|
|
||||||
target.Runtime,
|
|
||||||
DependencyContextStrings.NativeAssetType);
|
|
||||||
|
|
||||||
return runtime.Concat(native);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<JProperty> WriteRuntimeTargetAssemblies(IEnumerable<string> assemblies, string runtime, string assetType)
|
|
||||||
{
|
|
||||||
foreach (var assembly in assemblies)
|
|
||||||
{
|
|
||||||
yield return new JProperty(NormalizePath(assembly),
|
|
||||||
new JObject(
|
|
||||||
new JProperty(DependencyContextStrings.RidPropertyName, runtime),
|
|
||||||
new JProperty(DependencyContextStrings.AssetTypePropertyName, assetType)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private JObject WriteAssetList(IEnumerable<string> assetPaths)
|
|
||||||
{
|
|
||||||
return new JObject(assetPaths.Select(assembly => new JProperty(NormalizePath(assembly), new JObject())));
|
|
||||||
}
|
|
||||||
|
|
||||||
private JObject WriteLibraries(DependencyContext context)
|
|
||||||
{
|
|
||||||
var allLibraries =
|
|
||||||
context.RuntimeLibraries.Cast<Library>().Concat(context.CompileLibraries)
|
|
||||||
.GroupBy(library => library.Name + DependencyContextStrings.VersionSeperator + library.Version);
|
|
||||||
|
|
||||||
return new JObject(allLibraries.Select(libraries=> new JProperty(libraries.Key, WriteLibrary(libraries.First()))));
|
|
||||||
}
|
|
||||||
|
|
||||||
private JObject WriteLibrary(Library library)
|
|
||||||
{
|
|
||||||
return new JObject(
|
|
||||||
new JProperty(DependencyContextStrings.TypePropertyName, library.Type),
|
|
||||||
new JProperty(DependencyContextStrings.ServiceablePropertyName, library.Serviceable),
|
|
||||||
new JProperty(DependencyContextStrings.Sha512PropertyName, library.Hash)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string NormalizePath(string path)
|
|
||||||
{
|
|
||||||
return path.Replace('\\', '/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel
|
|
||||||
{
|
|
||||||
internal interface IDependencyContextReader
|
|
||||||
{
|
|
||||||
DependencyContext Read(Stream stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
// 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.Linq;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel
|
|
||||||
{
|
|
||||||
internal class Library
|
|
||||||
{
|
|
||||||
public Library(string type, string name, string version, string hash, IEnumerable<Dependency> dependencies, bool serviceable)
|
|
||||||
{
|
|
||||||
Type = type;
|
|
||||||
Name = name;
|
|
||||||
Version = version;
|
|
||||||
Hash = hash;
|
|
||||||
Dependencies = dependencies.ToArray();
|
|
||||||
Serviceable = serviceable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Type { get; }
|
|
||||||
|
|
||||||
public string Name { get; }
|
|
||||||
|
|
||||||
public string Version { get; }
|
|
||||||
|
|
||||||
public string Hash { get; }
|
|
||||||
|
|
||||||
public IReadOnlyList<Dependency> Dependencies { get; }
|
|
||||||
|
|
||||||
public bool Serviceable { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
// 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 Microsoft.Extensions.PlatformAbstractions;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel.Resolution
|
|
||||||
{
|
|
||||||
internal class AppBaseCompilationAssemblyResolver : ICompilationAssemblyResolver
|
|
||||||
{
|
|
||||||
private readonly string _basePath;
|
|
||||||
|
|
||||||
public AppBaseCompilationAssemblyResolver()
|
|
||||||
{
|
|
||||||
_basePath = PlatformServices.Default.Application.ApplicationBasePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> assemblies)
|
|
||||||
{
|
|
||||||
var isProject = string.Equals(library.Type, "project", StringComparison.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
if (!isProject &&
|
|
||||||
!string.Equals(library.Type, "package", StringComparison.OrdinalIgnoreCase) &&
|
|
||||||
!string.Equals(library.Type, "referenceassembly", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var refsPath = Path.Combine(_basePath, "refs");
|
|
||||||
var hasRefs = Directory.Exists(refsPath);
|
|
||||||
|
|
||||||
// Resolving packages and reference assebmlies requires refs folder to exist
|
|
||||||
if (!isProject && !hasRefs)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var directories = new List<string>()
|
|
||||||
{
|
|
||||||
_basePath
|
|
||||||
};
|
|
||||||
|
|
||||||
if (hasRefs)
|
|
||||||
{
|
|
||||||
directories.Insert(0, refsPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var assembly in library.Assemblies)
|
|
||||||
{
|
|
||||||
bool resolved = false;
|
|
||||||
var assemblyFile = Path.GetFileName(assembly);
|
|
||||||
foreach (var directory in directories)
|
|
||||||
{
|
|
||||||
string fullName;
|
|
||||||
if (ResolverUtils.TryResolveAssemblyFile(directory, assemblyFile, out fullName))
|
|
||||||
{
|
|
||||||
assemblies.Add(fullName);
|
|
||||||
resolved = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!resolved)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException(
|
|
||||||
$"Can not find assembly file {assemblyFile} at '{string.Join(",", directories)}'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
// 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.Resolution
|
|
||||||
{
|
|
||||||
internal class CompositeCompilationAssemblyResolver: ICompilationAssemblyResolver
|
|
||||||
{
|
|
||||||
private readonly ICompilationAssemblyResolver[] _resolvers;
|
|
||||||
|
|
||||||
public CompositeCompilationAssemblyResolver(ICompilationAssemblyResolver[] resolvers)
|
|
||||||
{
|
|
||||||
_resolvers = resolvers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> assemblies)
|
|
||||||
{
|
|
||||||
foreach (var resolver in _resolvers)
|
|
||||||
{
|
|
||||||
if (resolver.TryResolveAssemblyPaths(library, assemblies))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
// 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.IO;
|
|
||||||
using Microsoft.Extensions.PlatformAbstractions;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel.Resolution
|
|
||||||
{
|
|
||||||
internal class DotNetReferenceAssembliesPathResolver
|
|
||||||
{
|
|
||||||
public static readonly string DotNetReferenceAssembliesPathEnv = "DOTNET_REFERENCE_ASSEMBLIES_PATH";
|
|
||||||
|
|
||||||
internal static string Resolve(IRuntimeEnvironment runtimeEnvironment)
|
|
||||||
{
|
|
||||||
var path = Environment.GetEnvironmentVariable(DotNetReferenceAssembliesPathEnv);
|
|
||||||
if (!string.IsNullOrEmpty(path))
|
|
||||||
{
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetDefaultDotNetReferenceAssembliesPath(runtimeEnvironment);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string Resolve()
|
|
||||||
{
|
|
||||||
return Resolve(PlatformServices.Default.Runtime);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetDefaultDotNetReferenceAssembliesPath(IRuntimeEnvironment runtimeEnvironment)
|
|
||||||
{
|
|
||||||
var os = runtimeEnvironment.OperatingSystemPlatform;
|
|
||||||
|
|
||||||
if (os == Platform.Windows)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (os == Platform.Darwin &&
|
|
||||||
Directory.Exists("/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/xbuild-frameworks"))
|
|
||||||
{
|
|
||||||
return "/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/xbuild-frameworks";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Directory.Exists("/usr/local/lib/mono/xbuild-frameworks"))
|
|
||||||
{
|
|
||||||
return "/usr/local/lib/mono/xbuild-frameworks";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Directory.Exists("/usr/lib/mono/xbuild-frameworks"))
|
|
||||||
{
|
|
||||||
return "/usr/lib/mono/xbuild-frameworks";
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
// 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.Resolution
|
|
||||||
{
|
|
||||||
internal interface ICompilationAssemblyResolver
|
|
||||||
{
|
|
||||||
bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> assemblies);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
// 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;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel.Resolution
|
|
||||||
{
|
|
||||||
internal class PackageCacheCompilationAssemblyResolver: ICompilationAssemblyResolver
|
|
||||||
{
|
|
||||||
private readonly string _packageCacheDirectory;
|
|
||||||
|
|
||||||
internal PackageCacheCompilationAssemblyResolver()
|
|
||||||
{
|
|
||||||
_packageCacheDirectory = Environment.GetEnvironmentVariable("DOTNET_PACKAGES_CACHE");
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> assemblies)
|
|
||||||
{
|
|
||||||
if (!string.Equals(library.Type, "package", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(_packageCacheDirectory))
|
|
||||||
{
|
|
||||||
var hashSplitterPos = library.Hash.IndexOf('-');
|
|
||||||
if (hashSplitterPos <= 0 || hashSplitterPos == library.Hash.Length - 1)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"Invalid hash entry '{library.Hash}' for package '{library.Name}'");
|
|
||||||
}
|
|
||||||
|
|
||||||
string packagePath;
|
|
||||||
if (ResolverUtils.TryResolvePackagePath(library, _packageCacheDirectory, out packagePath))
|
|
||||||
{
|
|
||||||
var hashAlgorithm = library.Hash.Substring(0, hashSplitterPos);
|
|
||||||
var cacheHashPath = Path.Combine(packagePath, $"{library.Name}.{library.Version}.nupkg.{hashAlgorithm}");
|
|
||||||
|
|
||||||
if (File.Exists(cacheHashPath) &&
|
|
||||||
File.ReadAllText(cacheHashPath) == library.Hash.Substring(hashSplitterPos + 1))
|
|
||||||
{
|
|
||||||
assemblies.AddRange(ResolverUtils.ResolveFromPackagePath(library, packagePath));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
// 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 Microsoft.Extensions.PlatformAbstractions;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel.Resolution
|
|
||||||
{
|
|
||||||
internal class PackageCompilationAssemblyResolver: ICompilationAssemblyResolver
|
|
||||||
{
|
|
||||||
private readonly string _nugetPackageDirectory;
|
|
||||||
|
|
||||||
internal PackageCompilationAssemblyResolver()
|
|
||||||
{
|
|
||||||
_nugetPackageDirectory = GetDefaultPackageDirectory(PlatformServices.Default.Runtime);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static string GetDefaultPackageDirectory(IRuntimeEnvironment runtimeEnvironment)
|
|
||||||
{
|
|
||||||
var packageDirectory = Environment.GetEnvironmentVariable("NUGET_PACKAGES");
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(packageDirectory))
|
|
||||||
{
|
|
||||||
return packageDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
string basePath;
|
|
||||||
if (runtimeEnvironment.OperatingSystemPlatform == Platform.Windows)
|
|
||||||
{
|
|
||||||
basePath = Environment.GetEnvironmentVariable("USERPROFILE");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
basePath = Environment.GetEnvironmentVariable("HOME");
|
|
||||||
}
|
|
||||||
if (string.IsNullOrEmpty(basePath))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return Path.Combine(basePath, ".nuget", "packages");
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> assemblies)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(_nugetPackageDirectory) ||
|
|
||||||
!string.Equals(library.Type, "package", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
string packagePath;
|
|
||||||
|
|
||||||
if (ResolverUtils.TryResolvePackagePath(library, _nugetPackageDirectory, out packagePath))
|
|
||||||
{
|
|
||||||
assemblies.AddRange(ResolverUtils.ResolveFromPackagePath(library, packagePath));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,121 +0,0 @@
|
||||||
// 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 Microsoft.Extensions.PlatformAbstractions;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel.Resolution
|
|
||||||
{
|
|
||||||
internal class ReferenceAssemblyPathResolver: ICompilationAssemblyResolver
|
|
||||||
{
|
|
||||||
private readonly string _defaultReferenceAssembliesPath;
|
|
||||||
private readonly string[] _fallbackSearchPaths;
|
|
||||||
|
|
||||||
internal ReferenceAssemblyPathResolver()
|
|
||||||
{
|
|
||||||
_defaultReferenceAssembliesPath = GetDefaultReferenceAssembliesPath(PlatformServices.Default.Runtime);
|
|
||||||
_fallbackSearchPaths = GetFallbackSearchPaths(PlatformServices.Default.Runtime);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> assemblies)
|
|
||||||
{
|
|
||||||
if (!string.Equals(library.Type, "referenceassembly", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
foreach (var assembly in library.Assemblies)
|
|
||||||
{
|
|
||||||
string fullName;
|
|
||||||
if (!TryResolveReferenceAssembly(assembly, out fullName))
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"Can not find reference assembly '{assembly}' file for package {library.Name}");
|
|
||||||
}
|
|
||||||
assemblies.Add(fullName);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool TryResolveReferenceAssembly(string path, out string fullPath)
|
|
||||||
{
|
|
||||||
fullPath = null;
|
|
||||||
|
|
||||||
if (_defaultReferenceAssembliesPath != null)
|
|
||||||
{
|
|
||||||
var relativeToReferenceAssemblies = Path.Combine(_defaultReferenceAssembliesPath, path);
|
|
||||||
if (File.Exists(relativeToReferenceAssemblies))
|
|
||||||
{
|
|
||||||
fullPath = relativeToReferenceAssemblies;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var name = Path.GetFileName(path);
|
|
||||||
foreach (var fallbackPath in _fallbackSearchPaths)
|
|
||||||
{
|
|
||||||
var fallbackFile = Path.Combine(fallbackPath, name);
|
|
||||||
if (File.Exists(fallbackFile))
|
|
||||||
{
|
|
||||||
fullPath = fallbackFile;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static string[] GetFallbackSearchPaths(IRuntimeEnvironment runtimeEnvironment)
|
|
||||||
{
|
|
||||||
if (runtimeEnvironment.OperatingSystemPlatform != Platform.Windows)
|
|
||||||
{
|
|
||||||
return new string[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
var net20Dir = Path.Combine(Environment.GetEnvironmentVariable("WINDIR"), "Microsoft.NET", "Framework", "v2.0.50727");
|
|
||||||
|
|
||||||
if (!Directory.Exists(net20Dir))
|
|
||||||
{
|
|
||||||
return new string[0];
|
|
||||||
}
|
|
||||||
return new[] { net20Dir };
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static string GetDefaultReferenceAssembliesPath(IRuntimeEnvironment runtimeEnvironment)
|
|
||||||
{
|
|
||||||
// Allow setting the reference assemblies path via an environment variable
|
|
||||||
var referenceAssembliesPath = DotNetReferenceAssembliesPathResolver.Resolve(runtimeEnvironment);
|
|
||||||
if (!string.IsNullOrEmpty(referenceAssembliesPath))
|
|
||||||
{
|
|
||||||
return referenceAssembliesPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (runtimeEnvironment.OperatingSystemPlatform != Platform.Windows)
|
|
||||||
{
|
|
||||||
// There is no reference assemblies path outside of windows
|
|
||||||
// The environment variable can be used to specify one
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// References assemblies are in %ProgramFiles(x86)% on
|
|
||||||
// 64 bit machines
|
|
||||||
var programFiles = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(programFiles))
|
|
||||||
{
|
|
||||||
// On 32 bit machines they are in %ProgramFiles%
|
|
||||||
programFiles = Environment.GetEnvironmentVariable("ProgramFiles");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(programFiles))
|
|
||||||
{
|
|
||||||
// Reference assemblies aren't installed
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Path.Combine(
|
|
||||||
programFiles,
|
|
||||||
"Reference Assemblies", "Microsoft", "Framework");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
// 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;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel.Resolution
|
|
||||||
{
|
|
||||||
internal static class ResolverUtils
|
|
||||||
{
|
|
||||||
internal static bool TryResolvePackagePath(CompilationLibrary library, string basePath, out string packagePath)
|
|
||||||
{
|
|
||||||
packagePath = Path.Combine(basePath, library.Name, library.Version);
|
|
||||||
if (Directory.Exists(packagePath))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static IEnumerable<string> ResolveFromPackagePath(CompilationLibrary library, string basePath)
|
|
||||||
{
|
|
||||||
foreach (var assembly in library.Assemblies)
|
|
||||||
{
|
|
||||||
string fullName;
|
|
||||||
if (!TryResolveAssemblyFile(basePath, assembly, out fullName))
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"Can not find assembly file for package {library.Name} at '{fullName}'");
|
|
||||||
}
|
|
||||||
yield return fullName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static bool TryResolveAssemblyFile(string basePath, string assemblyPath, out string fullName)
|
|
||||||
{
|
|
||||||
fullName = Path.Combine(basePath, assemblyPath);
|
|
||||||
if (File.Exists(fullName))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
// 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 ResourceAssembly
|
|
||||||
{
|
|
||||||
public ResourceAssembly(string path, string locale)
|
|
||||||
{
|
|
||||||
Locale = locale;
|
|
||||||
Path = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Locale { get; set; }
|
|
||||||
|
|
||||||
public string Path { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
// 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.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel
|
|
||||||
{
|
|
||||||
internal class RuntimeAssembly
|
|
||||||
{
|
|
||||||
private const string NativeImageSufix = ".ni";
|
|
||||||
private readonly string _assemblyName;
|
|
||||||
|
|
||||||
public RuntimeAssembly(string assemblyName, string path)
|
|
||||||
{
|
|
||||||
_assemblyName = assemblyName;
|
|
||||||
Path = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AssemblyName Name => new AssemblyName(_assemblyName);
|
|
||||||
|
|
||||||
public string Path { get; }
|
|
||||||
|
|
||||||
public static RuntimeAssembly Create(string path)
|
|
||||||
{
|
|
||||||
var assemblyName = System.IO.Path.GetFileNameWithoutExtension(path);
|
|
||||||
if (assemblyName == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentException($"Provided path has empty file name '{path}'", nameof(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (assemblyName.EndsWith(NativeImageSufix))
|
|
||||||
{
|
|
||||||
assemblyName = assemblyName.Substring(0, assemblyName.Length - NativeImageSufix.Length);
|
|
||||||
}
|
|
||||||
return new RuntimeAssembly(assemblyName, path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
// 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.Linq;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel
|
|
||||||
{
|
|
||||||
internal class RuntimeFallbacks
|
|
||||||
{
|
|
||||||
public string Runtime { get; set; }
|
|
||||||
public IReadOnlyList<string> Fallbacks { get; set; }
|
|
||||||
|
|
||||||
public RuntimeFallbacks(string runtime, IEnumerable<string> fallbacks)
|
|
||||||
{
|
|
||||||
if (runtime == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(runtime));
|
|
||||||
}
|
|
||||||
if (fallbacks == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(fallbacks));
|
|
||||||
}
|
|
||||||
Runtime = runtime;
|
|
||||||
Fallbacks = fallbacks.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
// 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
|
|
||||||
{
|
|
||||||
internal class RuntimeLibrary : Library
|
|
||||||
{
|
|
||||||
public RuntimeLibrary(
|
|
||||||
string type,
|
|
||||||
string name,
|
|
||||||
string version,
|
|
||||||
string hash,
|
|
||||||
IEnumerable<RuntimeAssembly> assemblies,
|
|
||||||
IEnumerable<string> nativeLibraries,
|
|
||||||
IEnumerable<ResourceAssembly> resourceAssemblies,
|
|
||||||
IEnumerable<RuntimeTarget> subTargets,
|
|
||||||
IEnumerable<Dependency> dependencies,
|
|
||||||
bool serviceable)
|
|
||||||
: base(type, name, version, hash, dependencies, serviceable)
|
|
||||||
{
|
|
||||||
Assemblies = assemblies.ToArray();
|
|
||||||
ResourceAssemblies = resourceAssemblies.ToArray();
|
|
||||||
RuntimeTargets = subTargets.ToArray();
|
|
||||||
NativeLibraries = nativeLibraries.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IReadOnlyList<RuntimeAssembly> Assemblies { get; }
|
|
||||||
|
|
||||||
public IReadOnlyList<string> NativeLibraries { get; }
|
|
||||||
|
|
||||||
public IReadOnlyList<ResourceAssembly> ResourceAssemblies { get; }
|
|
||||||
|
|
||||||
public IReadOnlyList<RuntimeTarget> RuntimeTargets { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyModel
|
|
||||||
{
|
|
||||||
internal class RuntimeTarget
|
|
||||||
{
|
|
||||||
public RuntimeTarget(string runtime, IEnumerable<RuntimeAssembly> assemblies, IEnumerable<string> nativeLibraries)
|
|
||||||
{
|
|
||||||
Runtime = runtime;
|
|
||||||
Assemblies = assemblies.ToArray();
|
|
||||||
NativeLibraries = nativeLibraries.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Runtime { get; }
|
|
||||||
|
|
||||||
public IReadOnlyList<RuntimeAssembly> Assemblies { get; }
|
|
||||||
|
|
||||||
public IReadOnlyList<string> NativeLibraries { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4,11 +4,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.DependencyModel;
|
using Microsoft.Extensions.DependencyModel;
|
||||||
using Microsoft.Extensions.PlatformAbstractions;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||||
{
|
{
|
||||||
|
|
@ -18,6 +18,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DefaultAssemblyProvider : IAssemblyProvider
|
public class DefaultAssemblyProvider : IAssemblyProvider
|
||||||
{
|
{
|
||||||
|
private const string NativeImageSufix = ".ni";
|
||||||
private readonly Assembly _entryAssembly;
|
private readonly Assembly _entryAssembly;
|
||||||
private readonly DependencyContext _dependencyContext;
|
private readonly DependencyContext _dependencyContext;
|
||||||
|
|
||||||
|
|
@ -76,8 +77,9 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetCandidateLibraries()
|
return GetCandidateLibraries()
|
||||||
.SelectMany(l => l.Assemblies)
|
.SelectMany(library => library.RuntimeAssemblyGroups.GetDefaultGroup().AssetPaths)
|
||||||
.Select(Load);
|
.Select(Load)
|
||||||
|
.Where(assembly => assembly != null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,7 +90,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A set of <see cref="Library"/>.</returns>
|
/// <returns>A set of <see cref="Library"/>.</returns>
|
||||||
// Internal for unit testing
|
// Internal for unit testing
|
||||||
internal virtual IEnumerable<RuntimeLibrary> GetCandidateLibraries()
|
protected internal virtual IEnumerable<RuntimeLibrary> GetCandidateLibraries()
|
||||||
{
|
{
|
||||||
if (ReferenceAssemblies == null)
|
if (ReferenceAssemblies == null)
|
||||||
{
|
{
|
||||||
|
|
@ -98,9 +100,20 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||||
return _dependencyContext.RuntimeLibraries.Where(IsCandidateLibrary);
|
return _dependencyContext.RuntimeLibraries.Where(IsCandidateLibrary);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Assembly Load(RuntimeAssembly assembly)
|
private static Assembly Load(string assetPath)
|
||||||
{
|
{
|
||||||
return Assembly.Load(assembly.Name);
|
var name = Path.GetFileNameWithoutExtension(assetPath);
|
||||||
|
if (name != null)
|
||||||
|
{
|
||||||
|
if (name.EndsWith(NativeImageSufix, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
name = name.Substring(0, name.Length - NativeImageSufix.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Assembly.Load(new AssemblyName(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsCandidateLibrary(RuntimeLibrary library)
|
private bool IsCandidateLibrary(RuntimeLibrary library)
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
"version": "1.0.0-*"
|
"version": "1.0.0-*"
|
||||||
},
|
},
|
||||||
"Microsoft.Extensions.FileProviders.Abstractions": "1.0.0-*",
|
"Microsoft.Extensions.FileProviders.Abstractions": "1.0.0-*",
|
||||||
|
"Microsoft.Extensions.DependencyModel": "1.0.0-*",
|
||||||
"Microsoft.Extensions.ClosedGenericMatcher.Sources": {
|
"Microsoft.Extensions.ClosedGenericMatcher.Sources": {
|
||||||
"version": "1.0.0-*",
|
"version": "1.0.0-*",
|
||||||
"type": "build"
|
"type": "build"
|
||||||
|
|
@ -33,7 +34,6 @@
|
||||||
"type": "build",
|
"type": "build",
|
||||||
"version": "1.0.0-*"
|
"version": "1.0.0-*"
|
||||||
},
|
},
|
||||||
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-*",
|
|
||||||
"Microsoft.Extensions.PropertyActivator.Sources": {
|
"Microsoft.Extensions.PropertyActivator.Sources": {
|
||||||
"version": "1.0.0-*",
|
"version": "1.0.0-*",
|
||||||
"type": "build"
|
"type": "build"
|
||||||
|
|
@ -46,7 +46,6 @@
|
||||||
"version": "1.0.0-*",
|
"version": "1.0.0-*",
|
||||||
"type": "build"
|
"type": "build"
|
||||||
},
|
},
|
||||||
"Newtonsoft.Json": "8.0.3",
|
|
||||||
"System.Buffers": "4.0.0-*",
|
"System.Buffers": "4.0.0-*",
|
||||||
"System.Diagnostics.DiagnosticSource": "4.0.0-*"
|
"System.Diagnostics.DiagnosticSource": "4.0.0-*"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||||
{
|
{
|
||||||
var parseOptions = options.ParseOptions;
|
var parseOptions = options.ParseOptions;
|
||||||
parseOptions = parseOptions.WithPreprocessorSymbols(
|
parseOptions = parseOptions.WithPreprocessorSymbols(
|
||||||
parseOptions.PreprocessorSymbolNames.Concat(compilationOptions.Defines ?? Enumerable.Empty<string>()));
|
parseOptions.PreprocessorSymbolNames.Concat(compilationOptions.Defines));
|
||||||
|
|
||||||
LanguageVersion languageVersion;
|
LanguageVersion languageVersion;
|
||||||
if (!string.IsNullOrEmpty(compilationOptions.LanguageVersion) &&
|
if (!string.IsNullOrEmpty(compilationOptions.LanguageVersion) &&
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@
|
||||||
],
|
],
|
||||||
"xmlDoc": true
|
"xmlDoc": true
|
||||||
},
|
},
|
||||||
"compile": "../Microsoft.AspNetCore.Mvc.Core/DependencyContext/**/*.cs",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.AspNetCore.Mvc.Razor.Host": "1.0.0-*",
|
"Microsoft.AspNetCore.Mvc.Razor.Host": "1.0.0-*",
|
||||||
"Microsoft.AspNetCore.Mvc.ViewFeatures": "1.0.0-*",
|
"Microsoft.AspNetCore.Mvc.ViewFeatures": "1.0.0-*",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,221 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using Microsoft.Extensions.DependencyModel;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||||
|
{
|
||||||
|
public class DefaultAssemblyProviderTests
|
||||||
|
{
|
||||||
|
private static readonly Assembly CurrentAssembly = typeof(DefaultAssemblyProviderTests).GetTypeInfo().Assembly;
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetCandidateLibraries_IgnoresMvcAssemblies()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expected = GetLibrary("SomeRandomAssembly", "Microsoft.AspNetCore.Mvc.Abstractions");
|
||||||
|
var dependencyContext = new DependencyContext(
|
||||||
|
new TargetInfo("framework", "runtime", "signature", isPortable: true),
|
||||||
|
CompilationOptions.Default,
|
||||||
|
new CompilationLibrary[0],
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
GetLibrary("Microsoft.AspNetCore.Mvc.Core"),
|
||||||
|
GetLibrary("Microsoft.AspNetCore.Mvc"),
|
||||||
|
GetLibrary("Microsoft.AspNetCore.Mvc.Abstractions"),
|
||||||
|
expected,
|
||||||
|
},
|
||||||
|
Enumerable.Empty<RuntimeFallbacks>());
|
||||||
|
var provider = new DefaultAssemblyProvider(CurrentAssembly, dependencyContext);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var candidates = provider.GetCandidateLibraries();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(new[] { expected }, candidates);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CandidateAssemblies_ReturnsEntryAssemblyIfDependencyContextIsNull()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var provider = new DefaultAssemblyProvider(CurrentAssembly, dependencyContext: null);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var candidates = provider.CandidateAssemblies;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(new[] { CurrentAssembly }, candidates);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetCandidateLibraries_ReturnsLibrariesReferencingAnyMvcAssembly()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var dependencyContext = new DependencyContext(
|
||||||
|
new TargetInfo("framework", "runtime", "signature", isPortable: true),
|
||||||
|
CompilationOptions.Default,
|
||||||
|
new CompilationLibrary[0],
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
GetLibrary("Foo", "Microsoft.AspNetCore.Mvc.Core"),
|
||||||
|
GetLibrary("Bar", "Microsoft.AspNetCore.Mvc"),
|
||||||
|
GetLibrary("Qux", "Not.Mvc.Assembly", "Unofficial.Microsoft.AspNetCore.Mvc"),
|
||||||
|
GetLibrary("Baz", "Microsoft.AspNetCore.Mvc.Abstractions"),
|
||||||
|
},
|
||||||
|
Enumerable.Empty<RuntimeFallbacks>());
|
||||||
|
var provider = new DefaultAssemblyProvider(CurrentAssembly, dependencyContext);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var candidates = provider.GetCandidateLibraries();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(new[] { "Foo", "Bar", "Baz" }, candidates.Select(a => a.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetCandidateLibraries_ReturnsLibrariesReferencingOverriddenAssemblies()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var dependencyContext = new DependencyContext(
|
||||||
|
new TargetInfo("framework", "runtime", "signature", isPortable: true),
|
||||||
|
CompilationOptions.Default,
|
||||||
|
new CompilationLibrary[0],
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
GetLibrary("Foo", "CustomMvc.Modules"),
|
||||||
|
GetLibrary("Bar", "CustomMvc.Application.Loader"),
|
||||||
|
GetLibrary("Baz", "Microsoft.AspNetCore.Mvc.Abstractions"),
|
||||||
|
},
|
||||||
|
Enumerable.Empty<RuntimeFallbacks>());
|
||||||
|
var referenceAssemblies = new HashSet<string>
|
||||||
|
{
|
||||||
|
"CustomMvc.Modules",
|
||||||
|
"CustomMvc.Application.Loader"
|
||||||
|
};
|
||||||
|
var assemblyProvider = new OverridenAssemblyProvider(
|
||||||
|
CurrentAssembly,
|
||||||
|
dependencyContext,
|
||||||
|
referenceAssemblies);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var candidates = assemblyProvider.GetCandidateLibraries();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(new[] { "Foo", "Bar" }, candidates.Select(a => a.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetCandidateLibraries_ReturnsEmptySequenceWhenReferenceAssembliesIsNull()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var dependencyContext = new DependencyContext(
|
||||||
|
new TargetInfo("framework", "runtime", "signature", isPortable: true),
|
||||||
|
CompilationOptions.Default,
|
||||||
|
new CompilationLibrary[0],
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
GetLibrary("Foo", "CustomMvc.Modules"),
|
||||||
|
GetLibrary("Bar", "CustomMvc.Application.Loader"),
|
||||||
|
GetLibrary("Baz", "Microsoft.AspNetCore.Mvc.Abstractions"),
|
||||||
|
},
|
||||||
|
Enumerable.Empty<RuntimeFallbacks>());
|
||||||
|
var assemblyProvider = new OverridenAssemblyProvider(
|
||||||
|
CurrentAssembly,
|
||||||
|
dependencyContext,
|
||||||
|
referenceAssemblies: null);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var candidates = assemblyProvider.GetCandidateLibraries();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Empty(candidates);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test verifies DefaultAssemblyProvider.ReferenceAssemblies reflects the actual loadable assemblies
|
||||||
|
// of the libraries that Microsoft.AspNetCore.Mvc dependes on.
|
||||||
|
// If we add or remove dependencies, this test should be changed together.
|
||||||
|
[Fact]
|
||||||
|
public void ReferenceAssemblies_ReturnsLoadableReferenceAssemblies()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var provider = new TestableAssemblyProvider(CurrentAssembly, dependencyContext: null);
|
||||||
|
var excludeAssemblies = new string[]
|
||||||
|
{
|
||||||
|
"Microsoft.AspNetCore.Mvc.WebApiCompatShim",
|
||||||
|
"Microsoft.AspNetCore.Mvc.TestCommon",
|
||||||
|
"Microsoft.AspNetCore.Mvc.Core.Test",
|
||||||
|
"Microsoft.AspNetCore.Mvc.TestDiagnosticListener.Sources",
|
||||||
|
};
|
||||||
|
|
||||||
|
var additionalAssemblies = new[]
|
||||||
|
{
|
||||||
|
// The following assemblies are not reachable from Microsoft.AspNetCore.Mvc
|
||||||
|
"Microsoft.AspNetCore.Mvc.TagHelpers",
|
||||||
|
"Microsoft.AspNetCore.Mvc.Formatters.Xml",
|
||||||
|
};
|
||||||
|
|
||||||
|
var expected = DependencyContext.Load(CurrentAssembly)
|
||||||
|
.RuntimeLibraries
|
||||||
|
.Where(r => r.Name.StartsWith("Microsoft.AspNetCore.Mvc", StringComparison.Ordinal) &&
|
||||||
|
!excludeAssemblies.Contains(r.Name, StringComparer.OrdinalIgnoreCase))
|
||||||
|
.Select(r => r.Name)
|
||||||
|
.Concat(additionalAssemblies)
|
||||||
|
.Distinct()
|
||||||
|
.OrderBy(p => p, StringComparer.Ordinal);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var referenceAssemblies = provider.ReferenceAssemblies.OrderBy(p => p, StringComparer.Ordinal);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expected, referenceAssemblies);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RuntimeLibrary GetLibrary(string name, params string[] dependencyNames)
|
||||||
|
{
|
||||||
|
var dependencies = dependencyNames?.Select(d => new Dependency(d, "42.0.0")) ?? new Dependency[0];
|
||||||
|
|
||||||
|
return new RuntimeLibrary(
|
||||||
|
"package",
|
||||||
|
name,
|
||||||
|
"23.0.0",
|
||||||
|
"hash",
|
||||||
|
new RuntimeAssetGroup[0],
|
||||||
|
new RuntimeAssetGroup[0],
|
||||||
|
new ResourceAssembly[0],
|
||||||
|
dependencies: dependencies.ToArray(),
|
||||||
|
serviceable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class OverridenAssemblyProvider : DefaultAssemblyProvider
|
||||||
|
{
|
||||||
|
public OverridenAssemblyProvider(
|
||||||
|
Assembly entryAssembly,
|
||||||
|
DependencyContext dependencyContext,
|
||||||
|
HashSet<string> referenceAssemblies)
|
||||||
|
: base(entryAssembly, dependencyContext)
|
||||||
|
{
|
||||||
|
ReferenceAssemblies = referenceAssemblies;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override HashSet<string> ReferenceAssemblies { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestableAssemblyProvider : DefaultAssemblyProvider
|
||||||
|
{
|
||||||
|
public TestableAssemblyProvider(
|
||||||
|
Assembly entryAssembly,
|
||||||
|
DependencyContext dependencyContext)
|
||||||
|
: base(entryAssembly, dependencyContext)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public new HashSet<string> ReferenceAssemblies => base.ReferenceAssemblies;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,426 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Razor.Compilation;
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.Text;
|
||||||
|
using Microsoft.Extensions.DependencyModel;
|
||||||
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
using Microsoft.Extensions.Logging.Testing;
|
||||||
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||||
|
{
|
||||||
|
public class DefaultRoslynCompilationServiceTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Compile_ReturnsCompilationResult()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var content = @"
|
||||||
|
public class MyTestType {}";
|
||||||
|
|
||||||
|
var compilationService = new DefaultRoslynCompilationService(
|
||||||
|
GetDependencyContext(),
|
||||||
|
GetOptions(),
|
||||||
|
GetFileProviderAccessor(),
|
||||||
|
NullLoggerFactory.Instance);
|
||||||
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
|
new TestFileInfo { PhysicalPath = "SomePath" },
|
||||||
|
"some-relative-path");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = compilationService.Compile(relativeFileInfo, content);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("MyTestType", result.CompiledType.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Compile_ReturnsCompilationFailureWithPathsFromLinePragmas()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var viewPath = "some-relative-path";
|
||||||
|
var fileContent = "test file content";
|
||||||
|
var content = $@"
|
||||||
|
#line 1 ""{viewPath}""
|
||||||
|
this should fail";
|
||||||
|
var fileProvider = new TestFileProvider();
|
||||||
|
var fileInfo = fileProvider.AddFile(viewPath, fileContent);
|
||||||
|
|
||||||
|
var compilationService = new DefaultRoslynCompilationService(
|
||||||
|
GetDependencyContext(),
|
||||||
|
GetOptions(),
|
||||||
|
GetFileProviderAccessor(fileProvider),
|
||||||
|
NullLoggerFactory.Instance);
|
||||||
|
var relativeFileInfo = new RelativeFileInfo(fileInfo, "some-relative-path");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = compilationService.Compile(relativeFileInfo, content);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<CompilationResult>(result);
|
||||||
|
Assert.Null(result.CompiledType);
|
||||||
|
var compilationFailure = Assert.Single(result.CompilationFailures);
|
||||||
|
Assert.Equal(relativeFileInfo.RelativePath, compilationFailure.SourceFilePath);
|
||||||
|
Assert.Equal(fileContent, compilationFailure.SourceFileContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Compile_ReturnsGeneratedCodePath_IfLinePragmaIsNotAvailable()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var fileContent = "file content";
|
||||||
|
var content = @"this should fail";
|
||||||
|
|
||||||
|
var compilationService = new DefaultRoslynCompilationService(
|
||||||
|
GetDependencyContext(),
|
||||||
|
GetOptions(),
|
||||||
|
GetFileProviderAccessor(),
|
||||||
|
NullLoggerFactory.Instance);
|
||||||
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
|
new TestFileInfo { Content = fileContent },
|
||||||
|
"some-relative-path");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = compilationService.Compile(relativeFileInfo, content);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<CompilationResult>(result);
|
||||||
|
Assert.Null(result.CompiledType);
|
||||||
|
|
||||||
|
var compilationFailure = Assert.Single(result.CompilationFailures);
|
||||||
|
Assert.Equal("Generated Code", compilationFailure.SourceFilePath);
|
||||||
|
Assert.Equal(content, compilationFailure.SourceFileContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Compile_DoesNotThrow_IfFileCannotBeRead()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var path = "some-relative-path";
|
||||||
|
var content = $@"
|
||||||
|
#line 1 ""{path}""
|
||||||
|
this should fail";
|
||||||
|
|
||||||
|
var mockFileInfo = new Mock<IFileInfo>();
|
||||||
|
mockFileInfo.Setup(f => f.CreateReadStream())
|
||||||
|
.Throws(new Exception());
|
||||||
|
var fileProvider = new TestFileProvider();
|
||||||
|
fileProvider.AddFile(path, mockFileInfo.Object);
|
||||||
|
|
||||||
|
var compilationService = new DefaultRoslynCompilationService(
|
||||||
|
GetDependencyContext(),
|
||||||
|
GetOptions(),
|
||||||
|
GetFileProviderAccessor(),
|
||||||
|
NullLoggerFactory.Instance);
|
||||||
|
var relativeFileInfo = new RelativeFileInfo(mockFileInfo.Object, path);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = compilationService.Compile(relativeFileInfo, content);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<CompilationResult>(result);
|
||||||
|
Assert.Null(result.CompiledType);
|
||||||
|
var compilationFailure = Assert.Single(result.CompilationFailures);
|
||||||
|
Assert.Equal(path, compilationFailure.SourceFilePath);
|
||||||
|
Assert.Null(compilationFailure.SourceFileContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Compile_UsesApplicationsCompilationSettings_ForParsingAndCompilation()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var content = @"
|
||||||
|
#if MY_CUSTOM_DEFINE
|
||||||
|
public class MyCustomDefinedClass {}
|
||||||
|
#else
|
||||||
|
public class MyNonCustomDefinedClass {}
|
||||||
|
#endif
|
||||||
|
";
|
||||||
|
|
||||||
|
var options = GetOptions();
|
||||||
|
options.ParseOptions = options.ParseOptions.WithPreprocessorSymbols("MY_CUSTOM_DEFINE");
|
||||||
|
|
||||||
|
var compilationService = new DefaultRoslynCompilationService(
|
||||||
|
GetDependencyContext(),
|
||||||
|
options,
|
||||||
|
GetFileProviderAccessor(),
|
||||||
|
NullLoggerFactory.Instance);
|
||||||
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
|
new TestFileInfo { PhysicalPath = "SomePath" },
|
||||||
|
"some-relative-path");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = compilationService.Compile(relativeFileInfo, content);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(result.CompiledType);
|
||||||
|
Assert.Equal("MyCustomDefinedClass", result.CompiledType.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetCompilationFailedResult_ReturnsCompilationResult_WithGroupedMessages()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var viewPath = "Views/Home/Index";
|
||||||
|
var generatedCodeFileName = "Generated Code";
|
||||||
|
var fileProvider = new TestFileProvider();
|
||||||
|
fileProvider.AddFile(viewPath, "view-content");
|
||||||
|
var options = new RazorViewEngineOptions();
|
||||||
|
options.FileProviders.Add(fileProvider);
|
||||||
|
|
||||||
|
var compilationService = new DefaultRoslynCompilationService(
|
||||||
|
GetDependencyContext(),
|
||||||
|
options,
|
||||||
|
GetFileProviderAccessor(fileProvider),
|
||||||
|
NullLoggerFactory.Instance);
|
||||||
|
|
||||||
|
var assemblyName = "random-assembly-name";
|
||||||
|
|
||||||
|
var diagnostics = new[]
|
||||||
|
{
|
||||||
|
Diagnostic.Create(
|
||||||
|
GetDiagnosticDescriptor("message-1"),
|
||||||
|
Location.Create(
|
||||||
|
viewPath,
|
||||||
|
new TextSpan(10, 5),
|
||||||
|
new LinePositionSpan(new LinePosition(10, 1), new LinePosition(10, 2)))),
|
||||||
|
Diagnostic.Create(
|
||||||
|
GetDiagnosticDescriptor("message-2"),
|
||||||
|
Location.Create(
|
||||||
|
assemblyName,
|
||||||
|
new TextSpan(1, 6),
|
||||||
|
new LinePositionSpan(new LinePosition(1, 2), new LinePosition(3, 4)))),
|
||||||
|
Diagnostic.Create(
|
||||||
|
GetDiagnosticDescriptor("message-3"),
|
||||||
|
Location.Create(
|
||||||
|
viewPath,
|
||||||
|
new TextSpan(40, 50),
|
||||||
|
new LinePositionSpan(new LinePosition(30, 5), new LinePosition(40, 12)))),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var compilationResult = compilationService.GetCompilationFailedResult(
|
||||||
|
viewPath,
|
||||||
|
"compilation-content",
|
||||||
|
assemblyName,
|
||||||
|
diagnostics);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Collection(compilationResult.CompilationFailures,
|
||||||
|
failure =>
|
||||||
|
{
|
||||||
|
Assert.Equal(viewPath, failure.SourceFilePath);
|
||||||
|
Assert.Equal("view-content", failure.SourceFileContent);
|
||||||
|
Assert.Collection(failure.Messages,
|
||||||
|
message =>
|
||||||
|
{
|
||||||
|
Assert.Equal("message-1", message.Message);
|
||||||
|
Assert.Equal(viewPath, message.SourceFilePath);
|
||||||
|
Assert.Equal(11, message.StartLine);
|
||||||
|
Assert.Equal(2, message.StartColumn);
|
||||||
|
Assert.Equal(11, message.EndLine);
|
||||||
|
Assert.Equal(3, message.EndColumn);
|
||||||
|
},
|
||||||
|
message =>
|
||||||
|
{
|
||||||
|
Assert.Equal("message-3", message.Message);
|
||||||
|
Assert.Equal(viewPath, message.SourceFilePath);
|
||||||
|
Assert.Equal(31, message.StartLine);
|
||||||
|
Assert.Equal(6, message.StartColumn);
|
||||||
|
Assert.Equal(41, message.EndLine);
|
||||||
|
Assert.Equal(13, message.EndColumn);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
failure =>
|
||||||
|
{
|
||||||
|
Assert.Equal(generatedCodeFileName, failure.SourceFilePath);
|
||||||
|
Assert.Equal("compilation-content", failure.SourceFileContent);
|
||||||
|
Assert.Collection(failure.Messages,
|
||||||
|
message =>
|
||||||
|
{
|
||||||
|
Assert.Equal("message-2", message.Message);
|
||||||
|
Assert.Equal(assemblyName, message.SourceFilePath);
|
||||||
|
Assert.Equal(2, message.StartLine);
|
||||||
|
Assert.Equal(3, message.StartColumn);
|
||||||
|
Assert.Equal(4, message.EndLine);
|
||||||
|
Assert.Equal(5, message.EndColumn);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Compile_RunsCallback()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var content = "public class MyTestType {}";
|
||||||
|
RoslynCompilationContext usedCompilation = null;
|
||||||
|
|
||||||
|
var compilationService = new DefaultRoslynCompilationService(
|
||||||
|
GetDependencyContext(),
|
||||||
|
GetOptions(callback: c => usedCompilation = c),
|
||||||
|
GetFileProviderAccessor(),
|
||||||
|
NullLoggerFactory.Instance);
|
||||||
|
|
||||||
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
|
new TestFileInfo { PhysicalPath = "SomePath" },
|
||||||
|
"some-relative-path");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = compilationService.Compile(relativeFileInfo, content);
|
||||||
|
|
||||||
|
Assert.NotNull(usedCompilation);
|
||||||
|
Assert.Single(usedCompilation.Compilation.SyntaxTrees);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Compile_ThrowsIfDependencyContextIsNullAndTheApplicationFailsToCompileWithNoReferences()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var content = "public class MyTestType {}";
|
||||||
|
var compilationService = new DefaultRoslynCompilationService(
|
||||||
|
dependencyContext: null,
|
||||||
|
viewEngineOptions: GetOptions(),
|
||||||
|
fileProviderAccessor: GetFileProviderAccessor(),
|
||||||
|
loggerFactory: NullLoggerFactory.Instance);
|
||||||
|
|
||||||
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
|
new TestFileInfo { PhysicalPath = "SomePath" },
|
||||||
|
"some-relative-path.cshtml");
|
||||||
|
|
||||||
|
var expected = "The Razor page 'some-relative-path.cshtml' failed to compile. Ensure that your "
|
||||||
|
+ "application's project.json sets the 'preserveCompilationContext' compilation property.";
|
||||||
|
|
||||||
|
// Act and Assert
|
||||||
|
var ex = Assert.Throws<InvalidOperationException>(() =>
|
||||||
|
compilationService.Compile(relativeFileInfo, content));
|
||||||
|
Assert.Equal(expected, ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Compile_ThrowsIfDependencyContextReturnsNoReferencesAndTheApplicationFailsToCompile()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var content = "public class MyTestType {}";
|
||||||
|
var dependencyContext = new DependencyContext(
|
||||||
|
new TargetInfo("framework", "runtime", "signature", isPortable: true),
|
||||||
|
Extensions.DependencyModel.CompilationOptions.Default,
|
||||||
|
new CompilationLibrary[0],
|
||||||
|
new RuntimeLibrary[0],
|
||||||
|
Enumerable.Empty<RuntimeFallbacks>());
|
||||||
|
var compilationService = new DefaultRoslynCompilationService(
|
||||||
|
dependencyContext: dependencyContext,
|
||||||
|
viewEngineOptions: GetOptions(),
|
||||||
|
fileProviderAccessor: GetFileProviderAccessor(),
|
||||||
|
loggerFactory: NullLoggerFactory.Instance);
|
||||||
|
|
||||||
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
|
new TestFileInfo { PhysicalPath = "SomePath" },
|
||||||
|
"some-relative-path.cshtml");
|
||||||
|
|
||||||
|
var expected = "The Razor page 'some-relative-path.cshtml' failed to compile. Ensure that your "
|
||||||
|
+ "application's project.json sets the 'preserveCompilationContext' compilation property.";
|
||||||
|
|
||||||
|
// Act and Assert
|
||||||
|
var ex = Assert.Throws<InvalidOperationException>(() =>
|
||||||
|
compilationService.Compile(relativeFileInfo, content));
|
||||||
|
Assert.Equal(expected, ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Compile_DoesNotThrowIfReferencesWereClearedInCallback()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var options = GetOptions(context =>
|
||||||
|
{
|
||||||
|
context.Compilation = context.Compilation.RemoveAllReferences();
|
||||||
|
});
|
||||||
|
var content = "public class MyTestType {}";
|
||||||
|
var compilationService = new DefaultRoslynCompilationService(
|
||||||
|
dependencyContext: GetDependencyContext(),
|
||||||
|
viewEngineOptions: options,
|
||||||
|
fileProviderAccessor: GetFileProviderAccessor(),
|
||||||
|
loggerFactory: NullLoggerFactory.Instance);
|
||||||
|
|
||||||
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
|
new TestFileInfo { PhysicalPath = "SomePath" },
|
||||||
|
"some-relative-path.cshtml");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = compilationService.Compile(relativeFileInfo, content);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Single(result.CompilationFailures);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Compile_SucceedsIfReferencesAreAddedInCallback()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var options = GetOptions(context =>
|
||||||
|
{
|
||||||
|
var assemblyLocation = typeof(object).GetTypeInfo().Assembly.Location;
|
||||||
|
|
||||||
|
context.Compilation = context
|
||||||
|
.Compilation
|
||||||
|
.AddReferences(MetadataReference.CreateFromFile(assemblyLocation));
|
||||||
|
});
|
||||||
|
var content = "public class MyTestType {}";
|
||||||
|
var compilationService = new DefaultRoslynCompilationService(
|
||||||
|
dependencyContext: null,
|
||||||
|
viewEngineOptions: options,
|
||||||
|
fileProviderAccessor: GetFileProviderAccessor(),
|
||||||
|
loggerFactory: NullLoggerFactory.Instance);
|
||||||
|
|
||||||
|
var relativeFileInfo = new RelativeFileInfo(
|
||||||
|
new TestFileInfo { PhysicalPath = "SomePath" },
|
||||||
|
"some-relative-path.cshtml");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = compilationService.Compile(relativeFileInfo, content);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Null(result.CompilationFailures);
|
||||||
|
Assert.NotNull(result.CompiledType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DiagnosticDescriptor GetDiagnosticDescriptor(string messageFormat)
|
||||||
|
{
|
||||||
|
return new DiagnosticDescriptor(
|
||||||
|
id: "someid",
|
||||||
|
title: "sometitle",
|
||||||
|
messageFormat: messageFormat,
|
||||||
|
category: "some-category",
|
||||||
|
defaultSeverity: DiagnosticSeverity.Error,
|
||||||
|
isEnabledByDefault: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RazorViewEngineOptions GetOptions(Action<RoslynCompilationContext> callback = null)
|
||||||
|
{
|
||||||
|
return new RazorViewEngineOptions
|
||||||
|
{
|
||||||
|
CompilationCallback = callback ?? (c => { }),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private IRazorViewEngineFileProviderAccessor GetFileProviderAccessor(IFileProvider fileProvider = null)
|
||||||
|
{
|
||||||
|
var options = new Mock<IRazorViewEngineFileProviderAccessor>();
|
||||||
|
options.SetupGet(o => o.FileProvider)
|
||||||
|
.Returns(fileProvider ?? new TestFileProvider());
|
||||||
|
|
||||||
|
return options.Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DependencyContext GetDependencyContext()
|
||||||
|
{
|
||||||
|
var assembly = typeof(DefaultRoslynCompilationServiceTest).GetTypeInfo().Assembly;
|
||||||
|
return DependencyContext.Load(assembly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue