|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace Microsoft.NET.Build.Tests
{
public class GivenThatWeWantToReferenceAnAssembly : SdkTest
{
public GivenThatWeWantToReferenceAnAssembly(ITestOutputHelper log) : base(log)
{
}
[Theory]
[InlineData(ToolsetInfo.CurrentTargetFramework, "net40")]
[InlineData(ToolsetInfo.CurrentTargetFramework, "netstandard1.5")]
[InlineData(ToolsetInfo.CurrentTargetFramework, "net8.0")]
public void ItRunsAppsDirectlyReferencingAssemblies(
string referencerTarget,
string dependencyTarget)
{
if (!EnvironmentInfo.SupportsTargetFramework(referencerTarget))
{
return;
}
string identifier = referencerTarget.ToString() + "_" + dependencyTarget.ToString();
TestProject dependencyProject = new()
{
Name = "Dependency",
TargetFrameworks = dependencyTarget,
};
// Skip running test if not running on Windows
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !dependencyProject.BuildsOnNonWindows)
{
return;
}
dependencyProject.SourceFiles["Class1.cs"] = @"
public class Class1
{
public static string GetMessage()
{
return ""Hello from a direct reference."";
}
}
";
var dependencyAsset = _testAssetsManager.CreateTestProject(dependencyProject, identifier: identifier);
string dependencyAssemblyPath = RestoreAndBuild(dependencyAsset, dependencyProject);
TestProject referencerProject = new()
{
Name = "Referencer",
TargetFrameworks = referencerTarget,
IsExe = true,
};
referencerProject.References.Add(dependencyAssemblyPath);
referencerProject.SourceFiles["Program.cs"] = @"
using System;
public static class Program
{
public static void Main()
{
Console.WriteLine(Class1.GetMessage());
}
}
";
var referencerAsset = _testAssetsManager.CreateTestProject(referencerProject, identifier: identifier);
string applicationPath = RestoreAndBuild(referencerAsset, referencerProject);
new DotnetCommand(Log, applicationPath)
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello from a direct reference.");
}
[Theory]
[InlineData(ToolsetInfo.CurrentTargetFramework, "netstandard2.0")]
[InlineData(ToolsetInfo.CurrentTargetFramework, ToolsetInfo.CurrentTargetFramework)]
public void ItRunsAppsDirectlyReferencingAssembliesWithSatellites(
string referencerTarget,
string dependencyTarget)
{
if (!EnvironmentInfo.SupportsTargetFramework(referencerTarget))
{
return;
}
string identifier = referencerTarget.ToString() + "_" + dependencyTarget.ToString();
TestProject dependencyProject = new()
{
Name = "Dependency",
TargetFrameworks = dependencyTarget,
};
// Skip running test if not running on Windows
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !dependencyProject.BuildsOnNonWindows)
{
return;
}
dependencyProject.SourceFiles["Class1.cs"] = @"
using System;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Threading;
public class Class1
{
public static string GetMessage()
{
CultureInfo.CurrentUICulture = new CultureInfo(""en-US"");
var resources = new ResourceManager(""Dependency.Strings"", typeof(Class1).GetTypeInfo().Assembly);
return resources.GetString(""HelloWorld"");
}
}
";
dependencyProject.EmbeddedResources["Strings.en.resx"] = @"<?xml version=""1.0"" encoding=""utf-8""?>
<root>
<xsd:schema id=""root"" xmlns="""" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
<xsd:element name=""root"" msdata:IsDataSet=""true"">
<xsd:complexType>
<xsd:choice maxOccurs=""unbounded"">
<xsd:element name=""data"">
<xsd:complexType>
<xsd:sequence>
<xsd:element name=""value"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""1"" />
<xsd:element name=""comment"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""2"" />
</xsd:sequence>
<xsd:attribute name=""name"" type=""xsd:string"" msdata:Ordinal=""1"" />
<xsd:attribute name=""type"" type=""xsd:string"" msdata:Ordinal=""3"" />
<xsd:attribute name=""mimetype"" type=""xsd:string"" msdata:Ordinal=""4"" />
</xsd:complexType>
</xsd:element>
<xsd:element name=""resheader"">
<xsd:complexType>
<xsd:sequence>
<xsd:element name=""value"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""1"" />
</xsd:sequence>
<xsd:attribute name=""name"" type=""xsd:string"" use=""required"" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name=""resmimetype"">
<value>text/microsoft-resx</value>
</resheader>
<resheader name=""version"">
<value>1.3</value>
</resheader>
<resheader name=""reader"">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name=""writer"">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name=""HelloWorld"" xml:space=""preserve"">
<value>Hello World from en satellite assembly for a direct reference.</value>
</data>
</root>
";
var dependencyAsset = _testAssetsManager.CreateTestProject(dependencyProject, identifier: identifier);
string dependencyAssemblyPath = RestoreAndBuild(dependencyAsset, dependencyProject);
TestProject referencerProject = new()
{
Name = "Referencer",
TargetFrameworks = referencerTarget,
IsExe = true,
};
referencerProject.References.Add(dependencyAssemblyPath);
referencerProject.SourceFiles["Program.cs"] = @"
using System;
public static class Program
{
public static void Main()
{
Console.WriteLine(Class1.GetMessage());
}
}
";
var referencerAsset = _testAssetsManager.CreateTestProject(referencerProject, identifier: identifier);
string applicationPath = RestoreAndBuild(referencerAsset, referencerProject);
new DotnetCommand(Log, applicationPath)
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello World from en satellite assembly for a direct reference.");
}
[Theory]
[InlineData(ToolsetInfo.CurrentTargetFramework, "net40")]
[InlineData(ToolsetInfo.CurrentTargetFramework, "netstandard1.5")]
[InlineData(ToolsetInfo.CurrentTargetFramework, "net8.0")]
public void ItRunsAppsDirectlyReferencingAssembliesWhichReferenceAssemblies(
string referencerTarget,
string dllDependencyTarget)
{
if (!EnvironmentInfo.SupportsTargetFramework(referencerTarget))
{
return;
}
string identifier = referencerTarget.ToString() + "_" + dllDependencyTarget.ToString();
TestProject dllDependencyProjectDependency = new()
{
Name = "DllDependencyDependency",
TargetFrameworks = dllDependencyTarget,
};
dllDependencyProjectDependency.SourceFiles["Class2.cs"] = @"
public class Class2
{
public static string GetMessage()
{
return ""Hello from a reference of an indirect reference."";
}
}
";
// Skip running test if not running on Windows
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !dllDependencyProjectDependency.BuildsOnNonWindows)
{
return;
}
TestProject dllDependencyProject = new()
{
Name = "DllDependency",
TargetFrameworks = dllDependencyTarget,
};
dllDependencyProject.ReferencedProjects.Add(dllDependencyProjectDependency);
dllDependencyProject.SourceFiles["Class1.cs"] = @"
public class Class1
{
public static string GetMessage()
{
return Class2.GetMessage();
}
}
";
var dllDependencyAsset = _testAssetsManager.CreateTestProject(dllDependencyProject, identifier: identifier);
string dllDependencyAssemblyPath = RestoreAndBuild(dllDependencyAsset, dllDependencyProject);
TestProject referencerProject = new()
{
Name = "Referencer",
TargetFrameworks = referencerTarget,
IsExe = true,
};
referencerProject.References.Add(dllDependencyAssemblyPath);
referencerProject.SourceFiles["Program.cs"] = @"
using System;
public static class Program
{
public static void Main()
{
Console.WriteLine(Class1.GetMessage());
}
}
";
var referencerAsset = _testAssetsManager.CreateTestProject(referencerProject, identifier: identifier);
string applicationPath = RestoreAndBuild(referencerAsset, referencerProject);
new DotnetCommand(Log, applicationPath)
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello from a reference of an indirect reference.");
}
[Theory]
[InlineData(ToolsetInfo.CurrentTargetFramework, "netstandard2.0")]
[InlineData(ToolsetInfo.CurrentTargetFramework, ToolsetInfo.CurrentTargetFramework)]
public void ItRunsAppsDirectlyReferencingAssembliesWhichReferenceAssembliesWithSatellites(
string referencerTarget,
string dllDependencyTarget)
{
if (!EnvironmentInfo.SupportsTargetFramework(referencerTarget))
{
return;
}
string identifier = referencerTarget.ToString() + "_" + dllDependencyTarget.ToString();
TestProject dllDependencyProjectDependency = new()
{
Name = "DllDependencyDependency",
TargetFrameworks = dllDependencyTarget,
};
dllDependencyProjectDependency.SourceFiles["Class2.cs"] = @"
using System;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Threading;
public class Class2
{
public static string GetMessage()
{
CultureInfo.CurrentUICulture = new CultureInfo(""en-US"");
var resources = new ResourceManager(""DllDependencyDependency.Strings"", typeof(Class2).GetTypeInfo().Assembly);
return resources.GetString(""HelloWorld"");
}
}
";
dllDependencyProjectDependency.EmbeddedResources["Strings.en.resx"] = @"<?xml version=""1.0"" encoding=""utf-8""?>
<root>
<xsd:schema id=""root"" xmlns="""" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
<xsd:element name=""root"" msdata:IsDataSet=""true"">
<xsd:complexType>
<xsd:choice maxOccurs=""unbounded"">
<xsd:element name=""data"">
<xsd:complexType>
<xsd:sequence>
<xsd:element name=""value"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""1"" />
<xsd:element name=""comment"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""2"" />
</xsd:sequence>
<xsd:attribute name=""name"" type=""xsd:string"" msdata:Ordinal=""1"" />
<xsd:attribute name=""type"" type=""xsd:string"" msdata:Ordinal=""3"" />
<xsd:attribute name=""mimetype"" type=""xsd:string"" msdata:Ordinal=""4"" />
</xsd:complexType>
</xsd:element>
<xsd:element name=""resheader"">
<xsd:complexType>
<xsd:sequence>
<xsd:element name=""value"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""1"" />
</xsd:sequence>
<xsd:attribute name=""name"" type=""xsd:string"" use=""required"" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name=""resmimetype"">
<value>text/microsoft-resx</value>
</resheader>
<resheader name=""version"">
<value>1.3</value>
</resheader>
<resheader name=""reader"">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name=""writer"">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name=""HelloWorld"" xml:space=""preserve"">
<value>Hello World from en satellite assembly for a reference of an indirect reference.</value>
</data>
</root>
";
// Skip running test if not running on Windows
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !dllDependencyProjectDependency.BuildsOnNonWindows)
{
return;
}
TestProject dllDependencyProject = new()
{
Name = "DllDependency",
TargetFrameworks = dllDependencyTarget,
};
dllDependencyProject.ReferencedProjects.Add(dllDependencyProjectDependency);
dllDependencyProject.SourceFiles["Class1.cs"] = @"
public class Class1
{
public static string GetMessage()
{
return Class2.GetMessage();
}
}
";
var dllDependencyAsset = _testAssetsManager.CreateTestProject(dllDependencyProject, identifier: identifier);
string dllDependencyAssemblyPath = RestoreAndBuild(dllDependencyAsset, dllDependencyProject);
TestProject referencerProject = new()
{
Name = "Referencer",
TargetFrameworks = referencerTarget,
IsExe = true,
};
referencerProject.References.Add(dllDependencyAssemblyPath);
referencerProject.SourceFiles["Program.cs"] = @"
using System;
public static class Program
{
public static void Main()
{
Console.WriteLine(Class1.GetMessage());
}
}
";
var referencerAsset = _testAssetsManager.CreateTestProject(referencerProject, identifier: identifier);
string applicationPath = RestoreAndBuild(referencerAsset, referencerProject);
new DotnetCommand(Log, applicationPath)
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello World from en satellite assembly for a reference of an indirect reference.");
}
[Theory]
[InlineData(ToolsetInfo.CurrentTargetFramework, "netstandard2.0", "net40")]
[InlineData(ToolsetInfo.CurrentTargetFramework, "netstandard2.0", "netstandard1.5")]
[InlineData(ToolsetInfo.CurrentTargetFramework, "netstandard2.0", "net8.0")]
public void ItRunsAppsReferencingAProjectDirectlyReferencingAssemblies(
string referencerTarget,
string dependencyTarget,
string dllDependencyTarget)
{
if (!EnvironmentInfo.SupportsTargetFramework(referencerTarget))
{
return;
}
string identifier = referencerTarget.ToString() + "_" + dependencyTarget.ToString() + "_" + dllDependencyTarget.ToString();
TestProject dllDependencyProject = new()
{
Name = "DllDependency",
TargetFrameworks = dllDependencyTarget,
};
// Skip running test if not running on Windows
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !dllDependencyProject.BuildsOnNonWindows)
{
return;
}
dllDependencyProject.SourceFiles["Class2.cs"] = @"
public class Class2
{
public static string GetMessage()
{
return ""Hello from an indirect reference."";
}
}
";
var dllDependencyAsset = _testAssetsManager.CreateTestProject(dllDependencyProject, identifier: identifier);
string dllDependencyAssemblyPath = RestoreAndBuild(dllDependencyAsset, dllDependencyProject);
TestProject dependencyProject = new()
{
Name = "Dependency",
TargetFrameworks = dependencyTarget,
};
dependencyProject.References.Add(dllDependencyAssemblyPath);
dependencyProject.SourceFiles["Class1.cs"] = @"
public class Class1
{
public static string GetMessage()
{
return Class2.GetMessage();
}
}
";
TestProject referencerProject = new()
{
Name = "Referencer",
TargetFrameworks = referencerTarget,
IsExe = true,
};
referencerProject.ReferencedProjects.Add(dependencyProject);
referencerProject.SourceFiles["Program.cs"] = @"
using System;
public static class Program
{
public static void Main()
{
Console.WriteLine(Class1.GetMessage());
}
}
";
var referencerAsset = _testAssetsManager.CreateTestProject(referencerProject, identifier: identifier);
string applicationPath = RestoreAndBuild(referencerAsset, referencerProject);
new DotnetCommand(Log, applicationPath)
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello from an indirect reference.");
}
[Theory]
[InlineData(ToolsetInfo.CurrentTargetFramework, "netstandard2.0", "netstandard2.0")]
[InlineData(ToolsetInfo.CurrentTargetFramework, "netstandard2.0", ToolsetInfo.CurrentTargetFramework)]
public void ItRunsAppsReferencingAProjectDirectlyReferencingAssembliesWithSatellites(
string referencerTarget,
string dependencyTarget,
string dllDependencyTarget)
{
if (!EnvironmentInfo.SupportsTargetFramework(referencerTarget))
{
return;
}
string identifier = referencerTarget.ToString() + "_" + dependencyTarget.ToString() + "_" + dllDependencyTarget.ToString();
TestProject dllDependencyProject = new()
{
Name = "DllDependency",
TargetFrameworks = dllDependencyTarget,
};
// Skip running test if not running on Windows
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !dllDependencyProject.BuildsOnNonWindows)
{
return;
}
dllDependencyProject.SourceFiles["Class2.cs"] = @"
using System;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Threading;
public class Class2
{
public static string GetMessage()
{
CultureInfo.CurrentUICulture = new CultureInfo(""en-US"");
var resources = new ResourceManager(""DllDependency.Strings"", typeof(Class2).GetTypeInfo().Assembly);
return resources.GetString(""HelloWorld"");
}
}
";
dllDependencyProject.EmbeddedResources["Strings.en.resx"] = @"<?xml version=""1.0"" encoding=""utf-8""?>
<root>
<xsd:schema id=""root"" xmlns="""" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
<xsd:element name=""root"" msdata:IsDataSet=""true"">
<xsd:complexType>
<xsd:choice maxOccurs=""unbounded"">
<xsd:element name=""data"">
<xsd:complexType>
<xsd:sequence>
<xsd:element name=""value"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""1"" />
<xsd:element name=""comment"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""2"" />
</xsd:sequence>
<xsd:attribute name=""name"" type=""xsd:string"" msdata:Ordinal=""1"" />
<xsd:attribute name=""type"" type=""xsd:string"" msdata:Ordinal=""3"" />
<xsd:attribute name=""mimetype"" type=""xsd:string"" msdata:Ordinal=""4"" />
</xsd:complexType>
</xsd:element>
<xsd:element name=""resheader"">
<xsd:complexType>
<xsd:sequence>
<xsd:element name=""value"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""1"" />
</xsd:sequence>
<xsd:attribute name=""name"" type=""xsd:string"" use=""required"" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name=""resmimetype"">
<value>text/microsoft-resx</value>
</resheader>
<resheader name=""version"">
<value>1.3</value>
</resheader>
<resheader name=""reader"">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name=""writer"">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name=""HelloWorld"" xml:space=""preserve"">
<value>Hello World from en satellite assembly for an indirect reference.</value>
</data>
</root>
";
var dllDependencyAsset = _testAssetsManager.CreateTestProject(dllDependencyProject, identifier: identifier);
string dllDependencyAssemblyPath = RestoreAndBuild(dllDependencyAsset, dllDependencyProject);
TestProject dependencyProject = new()
{
Name = "Dependency",
TargetFrameworks = dependencyTarget,
};
dependencyProject.References.Add(dllDependencyAssemblyPath);
dependencyProject.SourceFiles["Class1.cs"] = @"
public class Class1
{
public static string GetMessage()
{
return Class2.GetMessage();
}
}
";
TestProject referencerProject = new()
{
Name = "Referencer",
TargetFrameworks = referencerTarget,
IsExe = true,
};
referencerProject.ReferencedProjects.Add(dependencyProject);
referencerProject.SourceFiles["Program.cs"] = @"
using System;
public static class Program
{
public static void Main()
{
Console.WriteLine(Class1.GetMessage());
}
}
";
var referencerAsset = _testAssetsManager.CreateTestProject(referencerProject, identifier: identifier);
string applicationPath = RestoreAndBuild(referencerAsset, referencerProject);
new DotnetCommand(Log, applicationPath)
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello World from en satellite assembly for an indirect reference.");
}
[Theory]
[InlineData(ToolsetInfo.CurrentTargetFramework, "netstandard2.0", "net40")]
[InlineData(ToolsetInfo.CurrentTargetFramework, "netstandard2.0", "netstandard1.5")]
[InlineData(ToolsetInfo.CurrentTargetFramework, "netstandard2.0", "net8.0")]
public void ItRunsAppsReferencingAProjectDirectlyReferencingAssembliesWhichReferenceAssemblies(
string referencerTarget,
string dependencyTarget,
string dllDependencyTarget)
{
if (!EnvironmentInfo.SupportsTargetFramework(referencerTarget))
{
return;
}
string identifier = referencerTarget.ToString() + "_" + dependencyTarget.ToString() + "_" + dllDependencyTarget.ToString();
TestProject dllDependencyProjectDependency = new()
{
Name = "DllDependencyDependency",
TargetFrameworks = dllDependencyTarget,
};
dllDependencyProjectDependency.SourceFiles["Class3.cs"] = @"
public class Class3
{
public static string GetMessage()
{
return ""Hello from a reference of an indirect reference."";
}
}
";
// Skip running test if not running on Windows
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !dllDependencyProjectDependency.BuildsOnNonWindows)
{
return;
}
TestProject dllDependencyProject = new()
{
Name = "DllDependency",
TargetFrameworks = dllDependencyTarget,
};
dllDependencyProject.ReferencedProjects.Add(dllDependencyProjectDependency);
dllDependencyProject.SourceFiles["Class2.cs"] = @"
public class Class2
{
public static string GetMessage()
{
return Class3.GetMessage();
}
}
";
var dllDependencyAsset = _testAssetsManager.CreateTestProject(dllDependencyProject, identifier: identifier);
string dllDependencyAssemblyPath = RestoreAndBuild(dllDependencyAsset, dllDependencyProject);
TestProject dependencyProject = new()
{
Name = "Dependency",
TargetFrameworks = dependencyTarget,
};
dependencyProject.References.Add(dllDependencyAssemblyPath);
dependencyProject.SourceFiles["Class1.cs"] = @"
public class Class1
{
public static string GetMessage()
{
return Class2.GetMessage();
}
}
";
TestProject referencerProject = new()
{
Name = "Referencer",
TargetFrameworks = referencerTarget,
IsExe = true,
};
referencerProject.ReferencedProjects.Add(dependencyProject);
referencerProject.SourceFiles["Program.cs"] = @"
using System;
public static class Program
{
public static void Main()
{
Console.WriteLine(Class1.GetMessage());
}
}
";
var referencerAsset = _testAssetsManager.CreateTestProject(referencerProject, identifier: identifier);
string applicationPath = RestoreAndBuild(referencerAsset, referencerProject);
new DotnetCommand(Log, applicationPath)
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello from a reference of an indirect reference.");
}
[Theory]
[InlineData(ToolsetInfo.CurrentTargetFramework, "netstandard2.0", "netstandard2.0")]
[InlineData(ToolsetInfo.CurrentTargetFramework, "netstandard2.0", ToolsetInfo.CurrentTargetFramework)]
public void ItRunsAppsReferencingAProjectDirectlyReferencingAssembliesWhichReferenceAssembliesWithSatellites(
string referencerTarget,
string dependencyTarget,
string dllDependencyTarget)
{
if (!EnvironmentInfo.SupportsTargetFramework(referencerTarget))
{
return;
}
string identifier = referencerTarget.ToString() + "_" + dependencyTarget.ToString() + "_" + dllDependencyTarget.ToString();
TestProject dllDependencyProjectDependency = new()
{
Name = "DllDependencyDependency",
TargetFrameworks = dllDependencyTarget,
};
dllDependencyProjectDependency.SourceFiles["Class3.cs"] = @"
using System;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Threading;
public class Class3
{
public static string GetMessage()
{
CultureInfo.CurrentUICulture = new CultureInfo(""en-US"");
var resources = new ResourceManager(""DllDependencyDependency.Strings"", typeof(Class3).GetTypeInfo().Assembly);
return resources.GetString(""HelloWorld"");
}
}
";
dllDependencyProjectDependency.EmbeddedResources["Strings.en.resx"] = @"<?xml version=""1.0"" encoding=""utf-8""?>
<root>
<xsd:schema id=""root"" xmlns="""" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
<xsd:element name=""root"" msdata:IsDataSet=""true"">
<xsd:complexType>
<xsd:choice maxOccurs=""unbounded"">
<xsd:element name=""data"">
<xsd:complexType>
<xsd:sequence>
<xsd:element name=""value"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""1"" />
<xsd:element name=""comment"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""2"" />
</xsd:sequence>
<xsd:attribute name=""name"" type=""xsd:string"" msdata:Ordinal=""1"" />
<xsd:attribute name=""type"" type=""xsd:string"" msdata:Ordinal=""3"" />
<xsd:attribute name=""mimetype"" type=""xsd:string"" msdata:Ordinal=""4"" />
</xsd:complexType>
</xsd:element>
<xsd:element name=""resheader"">
<xsd:complexType>
<xsd:sequence>
<xsd:element name=""value"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""1"" />
</xsd:sequence>
<xsd:attribute name=""name"" type=""xsd:string"" use=""required"" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name=""resmimetype"">
<value>text/microsoft-resx</value>
</resheader>
<resheader name=""version"">
<value>1.3</value>
</resheader>
<resheader name=""reader"">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name=""writer"">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name=""HelloWorld"" xml:space=""preserve"">
<value>Hello World from en satellite assembly for a reference of an indirect reference.</value>
</data>
</root>
";
// Skip running test if not running on Windows
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !dllDependencyProjectDependency.BuildsOnNonWindows)
{
return;
}
TestProject dllDependencyProject = new()
{
Name = "DllDependency",
TargetFrameworks = dllDependencyTarget,
};
dllDependencyProject.ReferencedProjects.Add(dllDependencyProjectDependency);
dllDependencyProject.SourceFiles["Class2.cs"] = @"
public class Class2
{
public static string GetMessage()
{
return Class3.GetMessage();
}
}
";
var dllDependencyAsset = _testAssetsManager.CreateTestProject(dllDependencyProject, identifier: identifier);
string dllDependencyAssemblyPath = RestoreAndBuild(dllDependencyAsset, dllDependencyProject);
TestProject dependencyProject = new()
{
Name = "Dependency",
TargetFrameworks = dependencyTarget,
};
dependencyProject.References.Add(dllDependencyAssemblyPath);
dependencyProject.SourceFiles["Class1.cs"] = @"
public class Class1
{
public static string GetMessage()
{
return Class2.GetMessage();
}
}
";
TestProject referencerProject = new()
{
Name = "Referencer",
TargetFrameworks = referencerTarget,
IsExe = true,
};
referencerProject.ReferencedProjects.Add(dependencyProject);
referencerProject.SourceFiles["Program.cs"] = @"
using System;
public static class Program
{
public static void Main()
{
Console.WriteLine(Class1.GetMessage());
}
}
";
var referencerAsset = _testAssetsManager.CreateTestProject(referencerProject, identifier: identifier);
string applicationPath = RestoreAndBuild(referencerAsset, referencerProject);
new DotnetCommand(Log, applicationPath)
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello World from en satellite assembly for a reference of an indirect reference.");
}
private string RestoreAndBuild(TestAsset testAsset, TestProject testProject)
{
var buildCommand = new BuildCommand(testAsset);
buildCommand.Execute()
.Should()
.Pass();
var outputDirectory = buildCommand.GetOutputDirectory(
testProject.TargetFrameworks,
runtimeIdentifier: testProject.RuntimeIdentifier);
return Path.Combine(outputDirectory.FullName, testProject.Name + ".dll");
}
}
}
|