Add reference assemblies and runtime targets support to dependency context builder.

This commit is contained in:
Pavel Krymets 2016-03-07 10:51:40 -08:00
parent 7cc90d9ad1
commit dd3c0f50db
24 changed files with 556 additions and 130 deletions

View file

@ -49,6 +49,16 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
/// </summary> /// </summary>
public IEnumerable<AnalyzerReference> AnalyzerReferences { get; } public IEnumerable<AnalyzerReference> AnalyzerReferences { get; }
/// <summary>
/// Get a list of runtime targets provided by this export.
/// </summary>
public IEnumerable<LibraryRuntimeTarget> RuntimeTargets { get; }
/// <summary>
/// Get a list of resource assemblies provided by this export.
/// </summary>
public IEnumerable<LibraryResourceAssembly> ResourceAssemblies { get; }
public LibraryExport(LibraryDescription library, public LibraryExport(LibraryDescription library,
IEnumerable<LibraryAsset> compileAssemblies, IEnumerable<LibraryAsset> compileAssemblies,
IEnumerable<LibraryAsset> sourceReferences, IEnumerable<LibraryAsset> sourceReferences,
@ -56,7 +66,9 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
IEnumerable<LibraryAsset> runtimeAssets, IEnumerable<LibraryAsset> runtimeAssets,
IEnumerable<LibraryAsset> nativeLibraries, IEnumerable<LibraryAsset> nativeLibraries,
IEnumerable<LibraryAsset> embeddedResources, IEnumerable<LibraryAsset> embeddedResources,
IEnumerable<AnalyzerReference> analyzers) IEnumerable<AnalyzerReference> analyzers,
IEnumerable<LibraryRuntimeTarget> runtimeTargets,
IEnumerable<LibraryResourceAssembly> resourceAssemblies)
{ {
Library = library; Library = library;
CompilationAssemblies = compileAssemblies; CompilationAssemblies = compileAssemblies;
@ -66,6 +78,8 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
NativeLibraries = nativeLibraries; NativeLibraries = nativeLibraries;
EmbeddedResources = embeddedResources; EmbeddedResources = embeddedResources;
AnalyzerReferences = analyzers; AnalyzerReferences = analyzers;
RuntimeTargets = runtimeTargets;
ResourceAssemblies = resourceAssemblies;
} }
private string DebuggerDisplay => Library.Identity.ToString(); private string DebuggerDisplay => Library.Identity.ToString();

View file

@ -26,6 +26,10 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
private IList<AnalyzerReference> _analyzerReferences; private IList<AnalyzerReference> _analyzerReferences;
private IList<LibraryRuntimeTarget> _runtimeTargets;
private IList<LibraryResourceAssembly> _resourceAssemblies;
public LibraryDescription Library { get; set; } public LibraryDescription Library { get; set; }
public IEnumerable<LibraryAsset> RuntimeAssemblies => _runtimeAssemblies; public IEnumerable<LibraryAsset> RuntimeAssemblies => _runtimeAssemblies;
@ -44,6 +48,10 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
public IEnumerable<AnalyzerReference> AnalyzerReferences => _analyzerReferences; public IEnumerable<AnalyzerReference> AnalyzerReferences => _analyzerReferences;
public IEnumerable<LibraryRuntimeTarget> RuntimeTargets => _runtimeTargets;
public IEnumerable<LibraryResourceAssembly> ResourceAssemblies => _resourceAssemblies;
public static LibraryExportBuilder Create(LibraryDescription library = null) public static LibraryExportBuilder Create(LibraryDescription library = null)
{ {
return new LibraryExportBuilder().WithLibrary(library); return new LibraryExportBuilder().WithLibrary(library);
@ -63,7 +71,9 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
RuntimeAssets ?? EmptyArray<LibraryAsset>.Value, RuntimeAssets ?? EmptyArray<LibraryAsset>.Value,
NativeLibraries ?? EmptyArray<LibraryAsset>.Value, NativeLibraries ?? EmptyArray<LibraryAsset>.Value,
EmbeddedResources ?? EmptyArray<LibraryAsset>.Value, EmbeddedResources ?? EmptyArray<LibraryAsset>.Value,
AnalyzerReferences ?? EmptyArray<AnalyzerReference>.Value); AnalyzerReferences ?? EmptyArray<AnalyzerReference>.Value,
RuntimeTargets ?? EmptyArray<LibraryRuntimeTarget>.Value,
ResourceAssemblies ?? EmptyArray<LibraryResourceAssembly>.Value);
} }
public LibraryExportBuilder WithLibrary(LibraryDescription libraryDescription) public LibraryExportBuilder WithLibrary(LibraryDescription libraryDescription)
@ -89,7 +99,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
Replace(ref _compilationAssemblies, assets); Replace(ref _compilationAssemblies, assets);
return this; return this;
} }
public LibraryExportBuilder WithSourceReferences(IEnumerable<LibraryAsset> assets) public LibraryExportBuilder WithSourceReferences(IEnumerable<LibraryAsset> assets)
{ {
Replace(ref _sourceReferences, assets); Replace(ref _sourceReferences, assets);
@ -114,6 +124,18 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
return this; return this;
} }
public LibraryExportBuilder WithRuntimeTargets(IEnumerable<LibraryRuntimeTarget> targets)
{
Replace(ref _runtimeTargets, targets);
return this;
}
public LibraryExportBuilder WithResourceAssemblies(IEnumerable<LibraryResourceAssembly> assemblies)
{
Replace(ref _resourceAssemblies, assemblies);
return this;
}
public LibraryExportBuilder AddRuntimeAssembly(LibraryAsset asset) public LibraryExportBuilder AddRuntimeAssembly(LibraryAsset asset)
{ {
Add(ref _runtimeAssemblies, asset); Add(ref _runtimeAssemblies, asset);
@ -156,9 +178,28 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
return this; return this;
} }
public LibraryExportBuilder AddRuntimeTarget(LibraryRuntimeTarget target)
{
Add(ref _runtimeTargets, target);
return this;
}
public LibraryExportBuilder AddResourceAssembly(LibraryResourceAssembly assembly)
{
Add(ref _resourceAssemblies, assembly);
return this;
}
private void Replace<T>(ref IList<T> list, IEnumerable<T> enumerable) private void Replace<T>(ref IList<T> list, IEnumerable<T> enumerable)
{ {
list = new List<T>(enumerable); if (enumerable == null)
{
list = null;
}
else
{
list = new List<T>(enumerable);
}
} }
private void Add<T>(ref IList<T> list, T item) private void Add<T>(ref IList<T> list, T item)

View file

@ -122,6 +122,8 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
.WithNativeLibraries(libraryExport.NativeLibraries) .WithNativeLibraries(libraryExport.NativeLibraries)
.WithEmbedddedResources(libraryExport.EmbeddedResources) .WithEmbedddedResources(libraryExport.EmbeddedResources)
.WithAnalyzerReference(analyzerReferences) .WithAnalyzerReference(analyzerReferences)
.WithResourceAssemblies(libraryExport.ResourceAssemblies)
.WithRuntimeTargets(libraryExport.RuntimeTargets)
.Build(); .Build();
} }
} }
@ -199,6 +201,28 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
} }
} }
} }
if (package.RuntimeTargets.Any())
{
foreach (var targetGroup in package.RuntimeTargets.GroupBy(t => t.Runtime))
{
var runtime = new List<LibraryAsset>();
var native = new List<LibraryAsset>();
foreach (var lockFileRuntimeTarget in targetGroup)
{
if (string.Equals(lockFileRuntimeTarget.AssetType, "native", StringComparison.OrdinalIgnoreCase))
{
native.Add(LibraryAsset.CreateFromRelativePath(package.Path, lockFileRuntimeTarget.Path));
}
else if (string.Equals(lockFileRuntimeTarget.AssetType, "runtime", StringComparison.OrdinalIgnoreCase))
{
runtime.Add(LibraryAsset.CreateFromRelativePath(package.Path, lockFileRuntimeTarget.Path));
}
}
builder.AddRuntimeTarget(new LibraryRuntimeTarget(targetGroup.Key, runtime, native));
}
}
return builder.Build(); return builder.Build();
} }

View file

@ -0,0 +1,18 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace Microsoft.DotNet.ProjectModel.Compilation
{
public class LibraryResourceAssembly
{
public LibraryResourceAssembly(LibraryAsset asset, string locale)
{
Asset = asset;
Locale = locale;
}
public LibraryAsset Asset { get; }
public string Locale { get; }
}
}

View file

@ -0,0 +1,32 @@
// 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.DotNet.ProjectModel.Compilation
{
public class LibraryRuntimeTarget
{
public LibraryRuntimeTarget(string runtime,
IEnumerable<LibraryAsset> runtimeAssemblies,
IEnumerable<LibraryAsset> nativeLibraries)
{
Runtime = runtime;
RuntimeAssemblies = runtimeAssemblies.ToArray();
NativeLibraries = nativeLibraries.ToArray();
}
public string Runtime { get; }
/// <summary>
/// Gets a list of fully-qualified paths to MSIL binaries required to run
/// </summary>
public IReadOnlyList<LibraryAsset> RuntimeAssemblies { get; }
/// <summary>
/// Gets a list of fully-qualified paths to native binaries required to run
/// </summary>
public IReadOnlyList<LibraryAsset> NativeLibraries { get; }
}
}

View file

@ -49,8 +49,8 @@ namespace Microsoft.Extensions.DependencyModel
runtime, runtime,
false, false,
GetCompilationOptions(compilerOptions), GetCompilationOptions(compilerOptions),
GetLibraries(compilationExports, dependencyLookup, runtime: false).Cast<CompilationLibrary>().ToArray(), GetLibraries(compilationExports, dependencyLookup, runtime: false).Cast<CompilationLibrary>(),
GetLibraries(runtimeExports, dependencyLookup, runtime: true).Cast<RuntimeLibrary>().ToArray(), GetLibraries(runtimeExports, dependencyLookup, runtime: true).Cast<RuntimeLibrary>(),
new KeyValuePair<string, string[]>[0]); new KeyValuePair<string, string[]>[0]);
} }
@ -107,14 +107,14 @@ namespace Microsoft.Extensions.DependencyModel
} }
} }
string[] assemblies; IEnumerable<string> assemblies;
if (type == LibraryType.ReferenceAssembly) if (type == LibraryType.ReferenceAssembly)
{ {
assemblies = ResolveReferenceAssembliesPath(libraryAssets); assemblies = ResolveReferenceAssembliesPath(libraryAssets);
} }
else else
{ {
assemblies = libraryAssets.Select(libraryAsset => libraryAsset.RelativePath).ToArray(); assemblies = libraryAssets.Select(libraryAsset => libraryAsset.RelativePath);
} }
if (runtime) if (runtime)
@ -124,9 +124,10 @@ namespace Microsoft.Extensions.DependencyModel
export.Library.Identity.Name, export.Library.Identity.Name,
export.Library.Identity.Version.ToString(), export.Library.Identity.Version.ToString(),
export.Library.Hash, export.Library.Hash,
assemblies.Select(RuntimeAssembly.Create).ToArray(), assemblies.Select(RuntimeAssembly.Create),
new RuntimeTarget[0], export.ResourceAssemblies.Select(CreateResourceAssembly),
libraryDependencies.ToArray(), export.RuntimeTargets.Select(CreateRuntimeTarget),
libraryDependencies,
serviceable serviceable
); );
} }
@ -138,15 +139,31 @@ namespace Microsoft.Extensions.DependencyModel
export.Library.Identity.Version.ToString(), export.Library.Identity.Version.ToString(),
export.Library.Hash, export.Library.Hash,
assemblies, assemblies,
libraryDependencies.ToArray(), libraryDependencies,
serviceable serviceable
); );
} }
} }
private string[] ResolveReferenceAssembliesPath(IEnumerable<LibraryAsset> libraryAssets) private ResourceAssembly CreateResourceAssembly(LibraryResourceAssembly resourceAssembly)
{
return new ResourceAssembly(
path: resourceAssembly.Asset.RelativePath,
locale: resourceAssembly.Locale
);
}
private RuntimeTarget CreateRuntimeTarget(LibraryRuntimeTarget runtimeTarget)
{
return new RuntimeTarget(
runtime: runtimeTarget.Runtime,
assemblies: runtimeTarget.RuntimeAssemblies.Select(a => RuntimeAssembly.Create(a.RelativePath)),
nativeLibraries: runtimeTarget.NativeLibraries.Select(l => l.RelativePath)
);
}
private IEnumerable<string> ResolveReferenceAssembliesPath(IEnumerable<LibraryAsset> libraryAssets)
{ {
var resolvedPaths = new List<string>();
var referenceAssembliesPath = var referenceAssembliesPath =
PathUtility.EnsureTrailingSlash(_referenceAssembliesPath); PathUtility.EnsureTrailingSlash(_referenceAssembliesPath);
foreach (var libraryAsset in libraryAssets) foreach (var libraryAsset in libraryAssets)
@ -155,14 +172,13 @@ namespace Microsoft.Extensions.DependencyModel
// if not, save only assembly name and try to find it somehow later // if not, save only assembly name and try to find it somehow later
if (libraryAsset.ResolvedPath.StartsWith(referenceAssembliesPath)) if (libraryAsset.ResolvedPath.StartsWith(referenceAssembliesPath))
{ {
resolvedPaths.Add(libraryAsset.ResolvedPath.Substring(referenceAssembliesPath.Length)); yield return libraryAsset.ResolvedPath.Substring(referenceAssembliesPath.Length);
} }
else else
{ {
resolvedPaths.Add(Path.GetFileName(libraryAsset.ResolvedPath)); yield return Path.GetFileName(libraryAsset.ResolvedPath);
} }
} }
return resolvedPaths.ToArray();
} }
} }
} }

View file

@ -170,6 +170,21 @@ namespace Microsoft.DotNet.ProjectModel.Graph
return library; return library;
} }
private static LockFileRuntimeTarget ReadRuntimeTarget(string property, JsonValue json)
{
var jsonObject = json as JsonObject;
if (jsonObject == null)
{
throw FileFormatException.Create("The value type is not an object.", json);
}
return new LockFileRuntimeTarget(
path: property,
runtime: jsonObject.ValueAsString("runtime"),
assetType: jsonObject.ValueAsString("assetType")
);
}
private static LockFileContentFile ReadContentFile(string property, JsonValue json) private static LockFileContentFile ReadContentFile(string property, JsonValue json)
{ {
var contentFile = new LockFileContentFile() var contentFile = new LockFileContentFile()

View file

@ -0,0 +1,21 @@
// 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.DotNet.ProjectModel.Graph
{
public class LockFileRuntimeTarget
{
public LockFileRuntimeTarget(string path, string runtime, string assetType)
{
Path = path;
Runtime = runtime;
AssetType = assetType;
}
public string Path { get; }
public string Runtime { get; }
public string AssetType { get; }
}
}

View file

@ -32,5 +32,7 @@ namespace Microsoft.DotNet.ProjectModel.Graph
public IList<LockFileItem> NativeLibraries { get; set; } = new List<LockFileItem>(); public IList<LockFileItem> NativeLibraries { get; set; } = new List<LockFileItem>();
public IList<LockFileContentFile> ContentFiles { get; set; } = new List<LockFileContentFile>(); public IList<LockFileContentFile> ContentFiles { get; set; } = new List<LockFileContentFile>();
public IList<LockFileRuntimeTarget> RuntimeTargets { get; set; } = new List<LockFileRuntimeTarget>();
} }
} }

View file

@ -32,7 +32,7 @@ namespace Microsoft.DotNet.ProjectModel
} }
private LockFileTargetLibrary Target { get; } private LockFileTargetLibrary Target { get; }
public LockFilePackageLibrary Library { get; } public LockFilePackageLibrary Library { get; }
public IEnumerable<LockFileItem> RuntimeAssemblies => FilterPlaceholders(Target.RuntimeAssemblies); public IEnumerable<LockFileItem> RuntimeAssemblies => FilterPlaceholders(Target.RuntimeAssemblies);
@ -45,6 +45,8 @@ namespace Microsoft.DotNet.ProjectModel
public IEnumerable<LockFileContentFile> ContentFiles => Target.ContentFiles; public IEnumerable<LockFileContentFile> ContentFiles => Target.ContentFiles;
public IEnumerable<LockFileRuntimeTarget> RuntimeTargets => Target.RuntimeTargets;
private IEnumerable<LockFileItem> FilterPlaceholders(IList<LockFileItem> items) private IEnumerable<LockFileItem> FilterPlaceholders(IList<LockFileItem> items)
{ {
return items.Where(a => !PackageDependencyProvider.IsPlaceholderFile(a)); return items.Where(a => !PackageDependencyProvider.IsPlaceholderFile(a));

View file

@ -3,16 +3,23 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.DependencyModel.Resolution; using Microsoft.Extensions.DependencyModel.Resolution;
namespace Microsoft.Extensions.DependencyModel namespace Microsoft.Extensions.DependencyModel
{ {
public class CompilationLibrary : Library public class CompilationLibrary : Library
{ {
public CompilationLibrary(string type, string name, string version, string hash, string[] assemblies, Dependency[] dependencies, bool serviceable) 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) : base(type, name, version, hash, dependencies, serviceable)
{ {
Assemblies = assemblies; Assemblies = assemblies.ToArray();
} }
public IReadOnlyList<string> Assemblies { get; } public IReadOnlyList<string> Assemblies { get; }

View file

@ -46,9 +46,10 @@ namespace Microsoft.Extensions.DependencyModel
name: identity.Item2, name: identity.Item2,
version: identity.Item3, version: identity.Item3,
hash: identity.Item4, hash: identity.Item4,
assemblies: packageGroup.Select(l => RuntimeAssembly.Create(l.AssetPath)).ToArray(), assemblies: packageGroup.Select(l => RuntimeAssembly.Create(l.AssetPath)),
subTargets: new RuntimeTarget[0], resourceAssemblies: Enumerable.Empty<ResourceAssembly>(),
dependencies: new Dependency[] { }, subTargets: Enumerable.Empty<RuntimeTarget>(),
dependencies: Enumerable.Empty<Dependency>(),
serviceable: false serviceable: false
)); ));
} }
@ -58,9 +59,9 @@ namespace Microsoft.Extensions.DependencyModel
runtime: string.Empty, runtime: string.Empty,
isPortable: false, isPortable: false,
compilationOptions: CompilationOptions.Default, compilationOptions: CompilationOptions.Default,
compileLibraries: new CompilationLibrary[] {}, compileLibraries: Enumerable.Empty<CompilationLibrary>(),
runtimeLibraries: runtimeLibraries.ToArray(), runtimeLibraries: runtimeLibraries.ToArray(),
runtimeGraph: new KeyValuePair<string, string[]>[0]); runtimeGraph: Enumerable.Empty<KeyValuePair<string, string[]>>());
} }
private Tuple<string, string, string, string> PackageIdentity(DepsFileLine line) private Tuple<string, string, string, string> PackageIdentity(DepsFileLine line)

View file

@ -173,7 +173,18 @@ namespace Microsoft.Extensions.DependencyModel
.Select(RuntimeAssembly.Create) .Select(RuntimeAssembly.Create)
.ToArray(); .ToArray();
return new RuntimeLibrary(stub.Type, name, version, stub.Hash, assemblies, runtimeTargets.ToArray(), dependencies, stub.Serviceable); var resourceAssemblies = ReadResourceAssemblies((JObject)libraryObject[DependencyContextStrings.ResourceAssembliesPropertyName]);
return new RuntimeLibrary(
type: stub.Type,
name: name,
version: version,
hash: stub.Hash,
assemblies: assemblies,
resourceAssemblies: resourceAssemblies,
subTargets: runtimeTargets.ToArray(),
dependencies: dependencies,
serviceable: stub.Serviceable);
} }
else else
{ {
@ -182,6 +193,21 @@ namespace Microsoft.Extensions.DependencyModel
} }
} }
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) private static IEnumerable<RuntimeTargetEntryStub> ReadRuntimeTargetEntries(JObject runtimeTargetObject)
{ {
if (runtimeTargetObject == null) if (runtimeTargetObject == null)

View file

@ -66,5 +66,9 @@ namespace Microsoft.Extensions.DependencyModel
internal const string RuntimeAssetType = "runtime"; internal const string RuntimeAssetType = "runtime";
internal const string NativeAssetType = "native"; internal const string NativeAssetType = "native";
internal const string ResourceAssembliesPropertyName = "resources";
internal const string LocalePropertyName = "locale";
} }
} }

View file

@ -140,49 +140,70 @@ namespace Microsoft.Extensions.DependencyModel
return targetObject; return targetObject;
} }
private void AddCompilationAssemblies(JObject libraryObject, IEnumerable<string> compilationAssemblies)
{
libraryObject.Add(new JProperty(DependencyContextStrings.CompileTimeAssembliesKey,
WriteAssemblies(compilationAssemblies))
);
}
private void AddRuntimeAssemblies(JObject libraryObject, IEnumerable<RuntimeAssembly> runtimeAssemblies)
{
libraryObject.Add(new JProperty(DependencyContextStrings.RuntimeAssembliesKey,
WriteAssemblies(runtimeAssemblies.Select(a => a.Path)))
);
}
private void AddDependencies(JObject libraryObject, IEnumerable<Dependency> dependencies)
{
libraryObject.Add(
new JProperty(DependencyContextStrings.DependenciesPropertyName,
new JObject(
dependencies.Select(dependency => new JProperty(dependency.Name, dependency.Version))))
);
}
private void AddResourceAssemblies(JObject libraryObject, IEnumerable<ResourceAssembly> resourceAssemblies)
{
libraryObject.Add(DependencyContextStrings.ResourceAssembliesPropertyName,
new JObject(resourceAssemblies.Select(a =>
new JProperty(a.Path, new JObject(new JProperty(DependencyContextStrings.LocalePropertyName, a.Locale))))
)
);
}
private JObject WriteTargetLibrary(Library library) private JObject WriteTargetLibrary(Library library)
{ {
string propertyName;
string[] assemblies;
var runtimeLibrary = library as RuntimeLibrary; var runtimeLibrary = library as RuntimeLibrary;
if (runtimeLibrary != null) if (runtimeLibrary != null)
{ {
propertyName = DependencyContextStrings.RuntimeAssembliesKey; var libraryObject = new JObject();
assemblies = runtimeLibrary.Assemblies.Select(assembly => assembly.Path).ToArray(); AddDependencies(libraryObject, runtimeLibrary.Dependencies);
AddRuntimeAssemblies(libraryObject, runtimeLibrary.Assemblies);
AddResourceAssemblies(libraryObject, runtimeLibrary.ResourceAssemblies);
return libraryObject;
} }
else
var compilationLibrary = library as CompilationLibrary;
if (compilationLibrary != null)
{ {
var compilationLibrary = library as CompilationLibrary; var libraryObject = new JObject();
if (compilationLibrary != null) AddDependencies(libraryObject, compilationLibrary.Dependencies);
{ AddCompilationAssemblies(libraryObject, compilationLibrary.Assemblies);
propertyName = DependencyContextStrings.CompileTimeAssembliesKey; return libraryObject;
assemblies = compilationLibrary.Assemblies.ToArray();
}
else
{
throw new NotSupportedException();
}
} }
throw new NotSupportedException();
return new JObject(
new JProperty(DependencyContextStrings.DependenciesPropertyName, WriteDependencies(library.Dependencies)),
new JProperty(propertyName,
WriteAssemblies(assemblies))
);
} }
private JObject WritePortableTargetLibrary(RuntimeLibrary runtimeLibrary, CompilationLibrary compilationLibrary) private JObject WritePortableTargetLibrary(RuntimeLibrary runtimeLibrary, CompilationLibrary compilationLibrary)
{ {
var libraryObject = new JObject();
var dependencies = new HashSet<Dependency>();
var libraryObject = new JObject();
var dependencies = new HashSet<Dependency>();
if (runtimeLibrary != null) if (runtimeLibrary != null)
{ {
libraryObject.Add(new JProperty(DependencyContextStrings.RuntimeAssembliesKey,
WriteAssemblies(runtimeLibrary.Assemblies.Select(a => a.Path)))
);
if (runtimeLibrary.RuntimeTargets.Any()) if (runtimeLibrary.RuntimeTargets.Any())
{ {
libraryObject.Add(new JProperty( libraryObject.Add(new JProperty(
@ -190,21 +211,20 @@ namespace Microsoft.Extensions.DependencyModel
new JObject(runtimeLibrary.RuntimeTargets.SelectMany(WriteRuntimeTarget))) new JObject(runtimeLibrary.RuntimeTargets.SelectMany(WriteRuntimeTarget)))
); );
} }
AddResourceAssemblies(libraryObject, runtimeLibrary.ResourceAssemblies);
AddRuntimeAssemblies(libraryObject, runtimeLibrary.Assemblies);
dependencies.UnionWith(runtimeLibrary.Dependencies); dependencies.UnionWith(runtimeLibrary.Dependencies);
} }
if (compilationLibrary != null) if (compilationLibrary != null)
{ {
libraryObject.Add(new JProperty(DependencyContextStrings.CompileTimeAssembliesKey, AddCompilationAssemblies(libraryObject, compilationLibrary.Assemblies);
WriteAssemblies(compilationLibrary.Assemblies))
);
dependencies.UnionWith(compilationLibrary.Dependencies); dependencies.UnionWith(compilationLibrary.Dependencies);
} }
libraryObject.Add( AddDependencies(libraryObject, dependencies);
new JProperty(DependencyContextStrings.DependenciesPropertyName, WriteDependencies(dependencies)));
return libraryObject; return libraryObject;
} }
@ -241,13 +261,6 @@ namespace Microsoft.Extensions.DependencyModel
return new JObject(assemblies.Select(assembly => new JProperty(assembly, new JObject()))); return new JObject(assemblies.Select(assembly => new JProperty(assembly, new JObject())));
} }
private JObject WriteDependencies(IEnumerable<Dependency> dependencies)
{
return new JObject(
dependencies.Select(dependency => new JProperty(dependency.Name, dependency.Version))
);
}
private JObject WriteLibraries(DependencyContext context) private JObject WriteLibraries(DependencyContext context)
{ {
var allLibraries = var allLibraries =

View file

@ -1,19 +1,20 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved. // 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. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
namespace Microsoft.Extensions.DependencyModel namespace Microsoft.Extensions.DependencyModel
{ {
public class Library public class Library
{ {
public Library(string type, string name, string version, string hash, Dependency[] dependencies, bool serviceable) public Library(string type, string name, string version, string hash, IEnumerable<Dependency> dependencies, bool serviceable)
{ {
Type = type; Type = type;
Name = name; Name = name;
Version = version; Version = version;
Hash = hash; Hash = hash;
Dependencies = dependencies; Dependencies = dependencies.ToArray();
Serviceable = serviceable; Serviceable = serviceable;
} }

View file

@ -0,0 +1,19 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace Microsoft.Extensions.DependencyModel
{
public class ResourceAssembly
{
public ResourceAssembly(string path, string locale)
{
Locale = locale;
Path = path;
}
public string Locale { get; set; }
public string Path { get; set; }
}
}

View file

@ -13,18 +13,22 @@ namespace Microsoft.Extensions.DependencyModel
string name, string name,
string version, string version,
string hash, string hash,
RuntimeAssembly[] assemblies, IEnumerable<RuntimeAssembly> assemblies,
RuntimeTarget[] subTargets, IEnumerable<ResourceAssembly> resourceAssemblies,
Dependency[] dependencies, IEnumerable<RuntimeTarget> subTargets,
IEnumerable<Dependency> dependencies,
bool serviceable) bool serviceable)
: base(type, name, version, hash, dependencies, serviceable) : base(type, name, version, hash, dependencies, serviceable)
{ {
Assemblies = assemblies; Assemblies = assemblies.ToArray();
RuntimeTargets = subTargets; ResourceAssemblies = resourceAssemblies.ToArray();
RuntimeTargets = subTargets.ToArray();
} }
public IReadOnlyList<RuntimeAssembly> Assemblies { get; } public IReadOnlyList<RuntimeAssembly> Assemblies { get; }
public IReadOnlyList<ResourceAssembly> ResourceAssemblies { get; }
public IReadOnlyList<RuntimeTarget> RuntimeTargets { get; } public IReadOnlyList<RuntimeTarget> RuntimeTargets { get; }
} }
} }

View file

@ -1,14 +1,15 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace Microsoft.Extensions.DependencyModel namespace Microsoft.Extensions.DependencyModel
{ {
public class RuntimeTarget public class RuntimeTarget
{ {
public RuntimeTarget(string runtime, IReadOnlyList<RuntimeAssembly> assemblies, IReadOnlyList<string> nativeLibraries) public RuntimeTarget(string runtime, IEnumerable<RuntimeAssembly> assemblies, IEnumerable<string> nativeLibraries)
{ {
Runtime = runtime; Runtime = runtime;
Assemblies = assemblies; Assemblies = assemblies.ToArray();
NativeLibraries = nativeLibraries; NativeLibraries = nativeLibraries.ToArray();
} }
public string Runtime { get; } public string Runtime { get; }

View file

@ -1,3 +1,6 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -15,36 +18,6 @@ namespace Microsoft.DotNet.ProjectModel.Tests
{ {
private const string PackagePath = "PackagePath"; private const string PackagePath = "PackagePath";
private LibraryExport ExportSingle(LibraryDescription description = null)
{
var rootProject = new Project()
{
Name = "RootProject",
CompilerName = "csc"
};
var rootProjectDescription = new ProjectDescription(
new LibraryRange(),
rootProject,
new LibraryRange[] { },
new TargetFrameworkInformation(),
true);
if (description == null)
{
description = rootProjectDescription;
}
else
{
description.Parents.Add(rootProjectDescription);
}
var libraryManager = new LibraryManager(new[] { description }, new DiagnosticMessage[] { }, "");
var allExports = new LibraryExporter(rootProjectDescription, libraryManager, "config", "runtime", "basepath", "solutionroot").GetAllExports();
var export = allExports.Single();
return export;
}
private PackageDescription CreateDescription(LockFileTargetLibrary target = null, LockFilePackageLibrary package = null) private PackageDescription CreateDescription(LockFileTargetLibrary target = null, LockFilePackageLibrary package = null)
{ {
return new PackageDescription(PackagePath, return new PackageDescription(PackagePath,
@ -54,7 +27,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
} }
[Fact] [Fact]
private void ExportsPackageNativeLibraries() public void ExportsPackageNativeLibraries()
{ {
var description = CreateDescription( var description = CreateDescription(
new LockFileTargetLibrary() new LockFileTargetLibrary()
@ -76,7 +49,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
} }
[Fact] [Fact]
private void ExportsPackageCompilationAssebmlies() public void ExportsPackageCompilationAssebmlies()
{ {
var description = CreateDescription( var description = CreateDescription(
new LockFileTargetLibrary() new LockFileTargetLibrary()
@ -98,7 +71,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
} }
[Fact] [Fact]
private void ExportsPackageRuntimeAssebmlies() public void ExportsPackageRuntimeAssebmlies()
{ {
var description = CreateDescription( var description = CreateDescription(
new LockFileTargetLibrary() new LockFileTargetLibrary()
@ -120,7 +93,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
} }
[Fact] [Fact]
private void ExportsSources() public void ExportsSources()
{ {
var description = CreateDescription( var description = CreateDescription(
package: new LockFilePackageLibrary() package: new LockFilePackageLibrary()
@ -142,7 +115,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
} }
[Fact] [Fact]
private void ExportsCopyToOutputContentFiles() public void ExportsCopyToOutputContentFiles()
{ {
var description = CreateDescription( var description = CreateDescription(
new LockFileTargetLibrary() new LockFileTargetLibrary()
@ -170,7 +143,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
[Fact] [Fact]
private void ExportsResourceContentFiles() public void ExportsResourceContentFiles()
{ {
var description = CreateDescription( var description = CreateDescription(
new LockFileTargetLibrary() new LockFileTargetLibrary()
@ -196,7 +169,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
} }
[Fact] [Fact]
private void ExportsCompileContentFiles() public void ExportsCompileContentFiles()
{ {
var description = CreateDescription( var description = CreateDescription(
new LockFileTargetLibrary() new LockFileTargetLibrary()
@ -224,7 +197,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
[Fact] [Fact]
private void SelectsContentFilesOfProjectCodeLanguage() public void SelectsContentFilesOfProjectCodeLanguage()
{ {
var description = CreateDescription( var description = CreateDescription(
new LockFileTargetLibrary() new LockFileTargetLibrary()
@ -264,7 +237,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
} }
[Fact] [Fact]
private void SelectsContentFilesWithNoLanguageIfProjectLanguageNotMathed() public void SelectsContentFilesWithNoLanguageIfProjectLanguageNotMathed()
{ {
var description = CreateDescription( var description = CreateDescription(
new LockFileTargetLibrary() new LockFileTargetLibrary()
@ -295,5 +268,84 @@ namespace Microsoft.DotNet.ProjectModel.Tests
libraryAsset.RelativePath.Should().Be(Path.Combine("content", "file.any")); libraryAsset.RelativePath.Should().Be(Path.Combine("content", "file.any"));
libraryAsset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "content", "file.any")); libraryAsset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "content", "file.any"));
} }
[Fact]
public void ExportsRuntimeTargets()
{
var win8Native = Path.Combine("native", "win8-x64", "Native.dll");
var win8Runtime = Path.Combine("runtime", "win8-x64", "Runtime.dll");
var linuxNative = Path.Combine("native", "linux", "Native.dll");
var description = CreateDescription(
new LockFileTargetLibrary()
{
RuntimeTargets = new List<LockFileRuntimeTarget>()
{
new LockFileRuntimeTarget(
path: win8Native,
runtime: "win8-x64",
assetType: "native"
),
new LockFileRuntimeTarget(
path: win8Runtime,
runtime: "win8-x64",
assetType: "runtime"
),
new LockFileRuntimeTarget(
path: linuxNative,
runtime: "linux",
assetType: "native"
),
}
});
var result = ExportSingle(description);
result.RuntimeTargets.Should().HaveCount(2);
var runtimeTarget = result.RuntimeTargets.Should().Contain(t => t.Runtime == "win8-x64").Subject;
var runtime = runtimeTarget.RuntimeAssemblies.Single();
runtime.RelativePath.Should().Be(win8Runtime);
runtime.ResolvedPath.Should().Be(Path.Combine(PackagePath, win8Runtime));
var native = runtimeTarget.NativeLibraries.Single();
native.RelativePath.Should().Be(win8Native);
native.ResolvedPath.Should().Be(Path.Combine(PackagePath, win8Native));
runtimeTarget = result.RuntimeTargets.Should().Contain(t => t.Runtime == "linux").Subject;
native = runtimeTarget.NativeLibraries.Single();
native.RelativePath.Should().Be(linuxNative);
native.ResolvedPath.Should().Be(Path.Combine(PackagePath, linuxNative));
}
private LibraryExport ExportSingle(LibraryDescription description = null)
{
var rootProject = new Project()
{
Name = "RootProject",
CompilerName = "csc"
};
var rootProjectDescription = new ProjectDescription(
new LibraryRange(),
rootProject,
new LibraryRange[] { },
new TargetFrameworkInformation(),
true);
if (description == null)
{
description = rootProjectDescription;
}
else
{
description.Parents.Add(rootProjectDescription);
}
var libraryManager = new LibraryManager(new[] { description }, new DiagnosticMessage[] { }, "");
var allExports = new LibraryExporter(rootProjectDescription, libraryManager, "config", "runtime", "basepath", "solutionroot").GetAllExports();
var export = allExports.Single();
return export;
}
} }
} }

View file

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.DependencyModel; using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.DependencyModel.Resolution; using Microsoft.Extensions.DependencyModel.Resolution;
using Moq; using Moq;
@ -54,7 +55,14 @@ namespace StreamForwarderTests
failTwo.Object failTwo.Object
}; };
var library = new CompilationLibrary(string.Empty, string.Empty, string.Empty, string.Empty, null, null, false); var library = new CompilationLibrary(
string.Empty,
string.Empty,
string.Empty,
string.Empty,
Enumerable.Empty<string>(),
Enumerable.Empty<Dependency>(),
false);
var resolver = new CompositeCompilationAssemblyResolver(resolvers); var resolver = new CompositeCompilationAssemblyResolver(resolvers);
var result = resolver.TryResolveAssemblyPaths(library, null); var result = resolver.TryResolveAssemblyPaths(library, null);
@ -82,7 +90,14 @@ namespace StreamForwarderTests
}; };
var assemblies = new List<string>(); var assemblies = new List<string>();
var library = new CompilationLibrary(string.Empty, string.Empty, string.Empty, string.Empty, null, null, false); var library = new CompilationLibrary(
string.Empty,
string.Empty,
string.Empty,
string.Empty,
Enumerable.Empty<string>(),
Enumerable.Empty<Dependency>(),
false);
var resolver = new CompositeCompilationAssemblyResolver(resolvers); var resolver = new CompositeCompilationAssemblyResolver(resolvers);
var result = resolver.TryResolveAssemblyPaths(library, assemblies); var result = resolver.TryResolveAssemblyPaths(library, assemblies);

View file

@ -104,9 +104,24 @@ namespace Microsoft.Extensions.DependencyModel.Tests
LibraryType.ReferenceAssembly, LibraryType.ReferenceAssembly,
LibraryDependencyType.Default) LibraryDependencyType.Default)
}), }),
resourceAssemblies: new[]
{
new LibraryResourceAssembly(
new LibraryAsset("Dll", "en-US/Pack.Age.resources.dll", ""),
"en-US"
)
},
runtimeAssemblies: new[] runtimeAssemblies: new[]
{ {
new LibraryAsset("Dll", "lib/Pack.Age.dll", ""), new LibraryAsset("Dll", "lib/Pack.Age.dll", ""),
},
runtimeTargets: new []
{
new LibraryRuntimeTarget(
"win8-x64",
new [] { new LibraryAsset("Dll", "win8-x64/Pack.Age.dll", "") },
new [] { new LibraryAsset("Dll", "win8-x64/Pack.Age.native.dll", "") }
)
} }
), ),
Export(ReferenceAssemblyDescription("System.Collections", Export(ReferenceAssemblyDescription("System.Collections",
@ -126,6 +141,11 @@ namespace Microsoft.Extensions.DependencyModel.Tests
lib.Version.Should().Be("1.2.3"); lib.Version.Should().Be("1.2.3");
lib.Dependencies.Should().OnlyContain(l => l.Name == "System.Collections" && l.Version == "3.3.3"); lib.Dependencies.Should().OnlyContain(l => l.Name == "System.Collections" && l.Version == "3.3.3");
lib.Assemblies.Should().OnlyContain(l => l.Path == "lib/Pack.Age.dll"); lib.Assemblies.Should().OnlyContain(l => l.Path == "lib/Pack.Age.dll");
lib.ResourceAssemblies.Should().OnlyContain(l => l.Path == "en-US/Pack.Age.resources.dll" && l.Locale == "en-US");
var target = lib.RuntimeTargets.Should().Contain(t => t.Runtime == "win8-x64").Subject;
target.Assemblies.Should().OnlyContain(l => l.Path == "win8-x64/Pack.Age.dll");
target.NativeLibraries.Should().OnlyContain(l => l == "win8-x64/Pack.Age.native.dll");
var asm = context.RuntimeLibraries.Should().Contain(l => l.Name == "System.Collections").Subject; var asm = context.RuntimeLibraries.Should().Contain(l => l.Name == "System.Collections").Subject;
asm.Type.Should().Be("referenceassembly"); asm.Type.Should().Be("referenceassembly");
@ -204,7 +224,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
public void SkipsBuildDependencies() public void SkipsBuildDependencies()
{ {
var context = Build(compilationExports: new[] var context = Build(compilationExports: new[]
{ {
Export(PackageDescription("Pack.Age", Export(PackageDescription("Pack.Age",
dependencies: new[] dependencies: new[]
{ {
@ -225,18 +245,16 @@ namespace Microsoft.Extensions.DependencyModel.Tests
private LibraryExport Export( private LibraryExport Export(
LibraryDescription description, LibraryDescription description,
IEnumerable<LibraryAsset> compilationAssemblies = null, IEnumerable<LibraryAsset> compilationAssemblies = null,
IEnumerable<LibraryAsset> runtimeAssemblies = null) IEnumerable<LibraryAsset> runtimeAssemblies = null,
IEnumerable<LibraryRuntimeTarget> runtimeTargets = null,
IEnumerable<LibraryResourceAssembly> resourceAssemblies = null)
{ {
return new LibraryExport( return LibraryExportBuilder.Create(description)
description, .WithCompilationAssemblies(compilationAssemblies)
compilationAssemblies ?? Enumerable.Empty<LibraryAsset>(), .WithRuntimeAssemblies(runtimeAssemblies)
Enumerable.Empty<LibraryAsset>(), .WithRuntimeTargets(runtimeTargets)
runtimeAssemblies ?? Enumerable.Empty<LibraryAsset>(), .WithResourceAssemblies(resourceAssemblies)
Enumerable.Empty<LibraryAsset>(), .Build();
Enumerable.Empty<LibraryAsset>(),
Enumerable.Empty<LibraryAsset>(),
Enumerable.Empty<AnalyzerReference>()
);
} }
private PackageDescription PackageDescription( private PackageDescription PackageDescription(

View file

@ -183,6 +183,9 @@ namespace Microsoft.Extensions.DependencyModel.Tests
""runtimeTargets"": { ""runtimeTargets"": {
""lib/win7/System.Banana.dll"": { ""assetType"": ""runtime"", ""rid"": ""win7-x64""}, ""lib/win7/System.Banana.dll"": { ""assetType"": ""runtime"", ""rid"": ""win7-x64""},
""lib/win7/Banana.dll"": { ""assetType"": ""native"", ""rid"": ""win7-x64""} ""lib/win7/Banana.dll"": { ""assetType"": ""native"", ""rid"": ""win7-x64""}
},
""resources"": {
""System.Banana.resources.dll"": { ""locale"": ""en-US"" }
} }
} }
} }
@ -211,6 +214,8 @@ namespace Microsoft.Extensions.DependencyModel.Tests
package.Type.Should().Be("package"); package.Type.Should().Be("package");
package.Serviceable.Should().Be(false); package.Serviceable.Should().Be(false);
package.Assemblies.Should().Contain(a => a.Path == "lib/dotnet5.4/System.Banana.dll"); package.Assemblies.Should().Contain(a => a.Path == "lib/dotnet5.4/System.Banana.dll");
package.ResourceAssemblies.Should().Contain(a => a.Path == "System.Banana.resources.dll")
.Subject.Locale.Should().Be("en-US");
var target = package.RuntimeTargets.Should().Contain(t => t.Runtime == "win7-x64").Subject; var target = package.RuntimeTargets.Should().Contain(t => t.Runtime == "win7-x64").Subject;
target.Assemblies.Should().Contain(a => a.Path == "lib/win7/System.Banana.dll"); target.Assemblies.Should().Contain(a => a.Path == "lib/win7/System.Banana.dll");

View file

@ -154,6 +154,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
"1.2.3", "1.2.3",
"HASH", "HASH",
new [] { RuntimeAssembly.Create("Banana.dll")}, new [] { RuntimeAssembly.Create("Banana.dll")},
new [] { new ResourceAssembly("en-US\\Banana.Resource.dll", "en-US")},
new [] new []
{ {
new RuntimeTarget("win7-x64", new RuntimeTarget("win7-x64",
@ -187,6 +188,10 @@ namespace Microsoft.Extensions.DependencyModel.Tests
nativeLibrary.Should().HavePropertyValue("rid", "win7-x64"); nativeLibrary.Should().HavePropertyValue("rid", "win7-x64");
nativeLibrary.Should().HavePropertyValue("assetType", "native"); nativeLibrary.Should().HavePropertyValue("assetType", "native");
var resourceAssemblies = library.Should().HavePropertyAsObject("resources").Subject;
var resourceAssembly = resourceAssemblies.Should().HavePropertyAsObject("en-US\\Banana.Resource.dll").Subject;
resourceAssembly.Should().HavePropertyValue("locale", "en-US");
//libraries //libraries
var libraries = result.Should().HavePropertyAsObject("libraries").Subject; var libraries = result.Should().HavePropertyAsObject("libraries").Subject;
library = libraries.Should().HavePropertyAsObject("PackageName/1.2.3").Subject; library = libraries.Should().HavePropertyAsObject("PackageName/1.2.3").Subject;
@ -224,6 +229,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
"1.2.3", "1.2.3",
"HASH", "HASH",
new [] { RuntimeAssembly.Create("Banana.dll")}, new [] { RuntimeAssembly.Create("Banana.dll")},
new ResourceAssembly[] {},
new [] new []
{ {
new RuntimeTarget("win7-x64", new RuntimeTarget("win7-x64",
@ -283,6 +289,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
"1.2.3", "1.2.3",
"HASH", "HASH",
new [] { RuntimeAssembly.Create("Banana.dll")}, new [] { RuntimeAssembly.Create("Banana.dll")},
new ResourceAssembly[] {},
new RuntimeTarget[] {}, new RuntimeTarget[] {},
new [] { new [] {
new Dependency("Fruits.Abstract.dll","2.0.0") new Dependency("Fruits.Abstract.dll","2.0.0")
@ -308,6 +315,74 @@ namespace Microsoft.Extensions.DependencyModel.Tests
library.Should().HavePropertyValue("serviceable", true); library.Should().HavePropertyValue("serviceable", true);
} }
[Fact]
public void WritesResourceAssembliesForNonPortable()
{
var result = Save(Create(
"Target",
"runtime",
false,
runtimeLibraries: new[]
{
new RuntimeLibrary(
"package",
"PackageName",
"1.2.3",
"HASH",
new RuntimeAssembly[] { },
new []
{
new ResourceAssembly("en-US/Fruits.resources.dll", "en-US")
},
new RuntimeTarget[] { },
new Dependency[] { },
true
),
}));
var targets = result.Should().HavePropertyAsObject("targets").Subject;
var target = targets.Should().HavePropertyAsObject("Target/runtime").Subject;
var library = target.Should().HavePropertyAsObject("PackageName/1.2.3").Subject;
var resources = library.Should().HavePropertyAsObject("resources").Subject;
var resource = resources.Should().HavePropertyAsObject("en-US/Fruits.resources.dll").Subject;
resource.Should().HavePropertyValue("locale", "en-US");
}
[Fact]
public void WritesResourceAssembliesForPortable()
{
var result = Save(Create(
"Target",
"runtime",
true,
runtimeLibraries: new[]
{
new RuntimeLibrary(
"package",
"PackageName",
"1.2.3",
"HASH",
new RuntimeAssembly[] { },
new []
{
new ResourceAssembly("en-US/Fruits.resources.dll", "en-US")
},
new RuntimeTarget[] { },
new Dependency[] { },
true
),
}));
var targets = result.Should().HavePropertyAsObject("targets").Subject;
var target = targets.Should().HavePropertyAsObject("Target").Subject;
var library = target.Should().HavePropertyAsObject("PackageName/1.2.3").Subject;
var resources = library.Should().HavePropertyAsObject("resources").Subject;
var resource = resources.Should().HavePropertyAsObject("en-US/Fruits.resources.dll").Subject;
resource.Should().HavePropertyValue("locale", "en-US");
}
[Fact] [Fact]
public void WritesCompilationOptions() public void WritesCompilationOptions()
{ {