fix equality issue in DependencyContextLoader (#2379)
When checking if the provided assembly is the Entry Point Assembly, we previously just checked if the AssemblyNames were equal, but it turns out AssemblyName doesn't implement Equals, so it was using Reference Equality, which fails. This change uses Assembly.Equals, which has an Equals implementation that works. Also adds some tests to ensure it's working. This unblocks scenarios where the EntityFramework `dotnet-ef` command was trying to read DependencyContext.Default but receiving a null reference.
This commit is contained in:
parent
3d157d0ec8
commit
803fef6a8b
10 changed files with 260 additions and 96 deletions
|
@ -0,0 +1,42 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.DependencyModel;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.DependencyContextTest
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
if(args.Length > 0 && args[0] == "--debug")
|
||||
{
|
||||
Console.WriteLine("Waiting for Debugger to attach, press ENTER to continue");
|
||||
Console.WriteLine($"Process ID: {System.Diagnostics.Process.GetCurrentProcess().Id}");
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
||||
if(DependencyContext.Default != null)
|
||||
{
|
||||
Console.WriteLine("DependencyContext.Default is set!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Error.WriteLine("DependencyContext.Default is NULL!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(DependencyContext.Default.RuntimeGraph.Any())
|
||||
{
|
||||
Console.WriteLine("DependencyContext.Default.RuntimeGraph has items!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("DependencyContext.Default.RuntimeGraph is empty!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
Console.WriteLine("Tests succeeded!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>55fba85c-ce60-4f98-8e97-bb9196e893f9</ProjectGuid>
|
||||
<RootNamespace>dotnet-dependency-context-test</RootNamespace>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\artifacts\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
"compilationOptions": {
|
||||
"emitEntryPoint": true
|
||||
},
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"type": "platform",
|
||||
"version": "1.0.0-rc2-24008"
|
||||
},
|
||||
"Microsoft.Extensions.DependencyModel": "1.0.0-*"
|
||||
},
|
||||
"frameworks": {
|
||||
"netstandard1.5": {
|
||||
"imports": [
|
||||
"dnxcore50",
|
||||
"portable-net45+win8"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
15
TestAssets/TestProjects/DependencyContextFromTool/Program.cs
Normal file
15
TestAssets/TestProjects/DependencyContextFromTool/Program.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// 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;
|
||||
|
||||
namespace DependencyContextFromTool
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Hi!");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"compilationOptions": {
|
||||
"emitEntryPoint": true
|
||||
},
|
||||
"dependencies": {},
|
||||
"frameworks": {
|
||||
"netstandardapp1.5": {
|
||||
"imports": [
|
||||
"dnxcore50",
|
||||
"portable-net45+win8"
|
||||
],
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"type": "platform",
|
||||
"version": "1.0.0-rc2-24008"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"dotnet-dependency-context-test": {
|
||||
"version": "1.0.0-*",
|
||||
"imports": [ "dnxcore50" ]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,137 +25,146 @@ namespace Microsoft.DotNet.Cli.Build
|
|||
|
||||
public static readonly dynamic[] Projects = new[]
|
||||
{
|
||||
new
|
||||
{
|
||||
Name = "dotnet-dependency-tool-invoker",
|
||||
IsTool = true,
|
||||
Path = "TestAssets/TestPackages/dotnet-dependency-tool-invoker",
|
||||
IsApplicable = new Func<bool>(() => CurrentPlatform.IsWindows),
|
||||
new
|
||||
{
|
||||
Name = "dotnet-dependency-context-test",
|
||||
IsTool = true,
|
||||
Path = "TestAssets/TestPackages/dotnet-dependency-context-test",
|
||||
IsApplicable = new Func<bool>(() => true),
|
||||
VersionSuffix = s_testPackageBuildVersionSuffix,
|
||||
Clean = true
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "dotnet-desktop-and-portable",
|
||||
IsTool = true,
|
||||
Path = "TestAssets/TestPackages/dotnet-desktop-and-portable",
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "dotnet-dependency-tool-invoker",
|
||||
IsTool = true,
|
||||
Path = "TestAssets/TestPackages/dotnet-dependency-tool-invoker",
|
||||
IsApplicable = new Func<bool>(() => CurrentPlatform.IsWindows),
|
||||
VersionSuffix = s_testPackageBuildVersionSuffix,
|
||||
Clean = true
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "dotnet-hello",
|
||||
IsTool = true,
|
||||
Path = "TestAssets/TestPackages/dotnet-hello/v1/dotnet-hello",
|
||||
IsApplicable = new Func<bool>(() => true),
|
||||
VersionSuffix = string.Empty,
|
||||
new
|
||||
{
|
||||
Name = "dotnet-desktop-and-portable",
|
||||
IsTool = true,
|
||||
Path = "TestAssets/TestPackages/dotnet-desktop-and-portable",
|
||||
IsApplicable = new Func<bool>(() => CurrentPlatform.IsWindows),
|
||||
VersionSuffix = s_testPackageBuildVersionSuffix,
|
||||
Clean = true
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "dotnet-hello",
|
||||
IsTool = true,
|
||||
Path = "TestAssets/TestPackages/dotnet-hello/v2/dotnet-hello",
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "dotnet-hello",
|
||||
IsTool = true,
|
||||
Path = "TestAssets/TestPackages/dotnet-hello/v1/dotnet-hello",
|
||||
IsApplicable = new Func<bool>(() => true),
|
||||
VersionSuffix = string.Empty,
|
||||
Clean = true
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "dotnet-portable",
|
||||
IsTool = true,
|
||||
Path = "TestAssets/TestPackages/dotnet-portable",
|
||||
new
|
||||
{
|
||||
Name = "dotnet-hello",
|
||||
IsTool = true,
|
||||
Path = "TestAssets/TestPackages/dotnet-hello/v2/dotnet-hello",
|
||||
IsApplicable = new Func<bool>(() => true),
|
||||
VersionSuffix = string.Empty,
|
||||
Clean = true
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.DotNet.Cli.Utils",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.DotNet.Cli.Utils",
|
||||
new
|
||||
{
|
||||
Name = "dotnet-portable",
|
||||
IsTool = true,
|
||||
Path = "TestAssets/TestPackages/dotnet-portable",
|
||||
IsApplicable = new Func<bool>(() => true),
|
||||
VersionSuffix = string.Empty,
|
||||
Clean = true
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.DotNet.Cli.Utils",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.DotNet.Cli.Utils",
|
||||
IsApplicable = new Func<bool>(() => true),
|
||||
VersionSuffix = s_testPackageBuildVersionSuffix,
|
||||
Clean = false
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.DotNet.ProjectModel",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.DotNet.ProjectModel",
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.DotNet.ProjectModel",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.DotNet.ProjectModel",
|
||||
IsApplicable = new Func<bool>(() => true),
|
||||
VersionSuffix = s_testPackageBuildVersionSuffix,
|
||||
Clean = false
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.DotNet.ProjectModel.Loader",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.DotNet.ProjectModel.Loader",
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.DotNet.ProjectModel.Loader",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.DotNet.ProjectModel.Loader",
|
||||
IsApplicable = new Func<bool>(() => true),
|
||||
VersionSuffix = s_testPackageBuildVersionSuffix,
|
||||
Clean = false
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.DotNet.ProjectModel.Workspaces",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.DotNet.ProjectModel.Workspaces",
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.DotNet.ProjectModel.Workspaces",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.DotNet.ProjectModel.Workspaces",
|
||||
IsApplicable = new Func<bool>(() => true),
|
||||
VersionSuffix = s_testPackageBuildVersionSuffix,
|
||||
Clean = false
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.DotNet.InternalAbstractions",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.DotNet.InternalAbstractions",
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.DotNet.InternalAbstractions",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.DotNet.InternalAbstractions",
|
||||
IsApplicable = new Func<bool>(() => true),
|
||||
VersionSuffix = s_testPackageBuildVersionSuffix,
|
||||
Clean = false
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.Extensions.DependencyModel",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.Extensions.DependencyModel",
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.Extensions.DependencyModel",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.Extensions.DependencyModel",
|
||||
IsApplicable = new Func<bool>(() => true),
|
||||
VersionSuffix = s_testPackageBuildVersionSuffix,
|
||||
Clean = false
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.Extensions.Testing.Abstractions",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.Extensions.Testing.Abstractions",
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.Extensions.Testing.Abstractions",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.Extensions.Testing.Abstractions",
|
||||
IsApplicable = new Func<bool>(() => true),
|
||||
VersionSuffix = s_testPackageBuildVersionSuffix,
|
||||
Clean = false
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.DotNet.Compiler.Common",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.DotNet.Compiler.Common",
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.DotNet.Compiler.Common",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.DotNet.Compiler.Common",
|
||||
IsApplicable = new Func<bool>(() => true),
|
||||
VersionSuffix = s_testPackageBuildVersionSuffix,
|
||||
Clean = false
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.DotNet.Files",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.DotNet.Files",
|
||||
new
|
||||
{
|
||||
Name = "Microsoft.DotNet.Files",
|
||||
IsTool = true,
|
||||
Path = "src/Microsoft.DotNet.Files",
|
||||
IsApplicable = new Func<bool>(() => true),
|
||||
VersionSuffix = s_testPackageBuildVersionSuffix,
|
||||
Clean = false
|
||||
},
|
||||
new
|
||||
{
|
||||
Name = "dotnet-compile-fsc",
|
||||
IsTool = true,
|
||||
Path = "src/dotnet-compile-fsc",
|
||||
new
|
||||
{
|
||||
Name = "dotnet-compile-fsc",
|
||||
IsTool = true,
|
||||
Path = "src/dotnet-compile-fsc",
|
||||
IsApplicable = new Func<bool>(() => true),
|
||||
VersionSuffix = s_testPackageBuildVersionSuffix,
|
||||
Clean = true
|
||||
|
|
|
@ -37,17 +37,17 @@ namespace Microsoft.DotNet.Cli.Build
|
|||
"dotnet-test.Tests",
|
||||
"Kestrel.Tests"
|
||||
};
|
||||
|
||||
|
||||
public static readonly dynamic[] ConditionalTestAssets = new[]
|
||||
{
|
||||
new { Path = "AppWithDirectDependencyDesktopAndPortable", Skip = new Func<bool>(() => !CurrentPlatform.IsWindows) }
|
||||
new { Path = "AppWithDirectDependencyDesktopAndPortable", Skip = new Func<bool>(() => !CurrentPlatform.IsWindows) }
|
||||
};
|
||||
|
||||
[Target(
|
||||
nameof(PrepareTargets.Init),
|
||||
nameof(SetupTests),
|
||||
nameof(RestoreTests),
|
||||
nameof(BuildTests),
|
||||
nameof(PrepareTargets.Init),
|
||||
nameof(SetupTests),
|
||||
nameof(RestoreTests),
|
||||
nameof(BuildTests),
|
||||
nameof(RunTests),
|
||||
nameof(ValidateDependencies))]
|
||||
public static BuildTargetResult Test(BuildTargetContext c) => c.Success();
|
||||
|
@ -128,13 +128,13 @@ namespace Microsoft.DotNet.Cli.Build
|
|||
{
|
||||
var dotnet = DotNetCli.Stage2;
|
||||
|
||||
dotnet.Restore("--verbosity", "verbose",
|
||||
dotnet.Restore("--verbosity", "verbose",
|
||||
"--infer-runtimes",
|
||||
"--fallbacksource", Dirs.TestPackages,
|
||||
"--fallbacksource", Dirs.Corehost)
|
||||
.WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "DesktopTestProjects"))
|
||||
.Execute().EnsureSuccessful();
|
||||
|
||||
|
||||
return c.Success();
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ namespace Microsoft.DotNet.Cli.Build
|
|||
{
|
||||
versionSuffix = c.BuildContext.Get<BuildVersion>("BuildVersion").VersionSuffix;
|
||||
}
|
||||
|
||||
|
||||
var fullPath = Path.Combine(c.BuildContext.BuildDirectory, relativePath.Replace('/', Path.DirectorySeparatorChar));
|
||||
c.Info($"Packing: {fullPath}");
|
||||
|
||||
|
@ -187,14 +187,14 @@ namespace Microsoft.DotNet.Cli.Build
|
|||
var packBuildResult = DotNetCli.Stage1.Build(buildArgs.ToArray())
|
||||
.Execute();
|
||||
}
|
||||
|
||||
|
||||
|
||||
var projectJson = Path.Combine(fullPath, "project.json");
|
||||
var dotnetPackArgs = new List<string> {
|
||||
var dotnetPackArgs = new List<string> {
|
||||
projectJson,
|
||||
"--no-build",
|
||||
"--build-base-path", Dirs.TestPackagesBuild,
|
||||
"--output", Dirs.TestPackages
|
||||
"--output", Dirs.TestPackages
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(versionSuffix))
|
||||
|
@ -217,7 +217,7 @@ namespace Microsoft.DotNet.Cli.Build
|
|||
foreach (var packageName in PackageTargets.ProjectsToPack)
|
||||
{
|
||||
Rmdir(Path.Combine(Dirs.NuGetPackages, packageName));
|
||||
}
|
||||
}
|
||||
|
||||
return c.Success();
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ namespace Microsoft.DotNet.Cli.Build
|
|||
{
|
||||
Rmdir(Path.Combine(Dirs.NuGetPackages, ".tools", packageProject.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c.Success();
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace Microsoft.Extensions.DependencyModel
|
|||
|
||||
internal virtual bool IsEntryAssembly(Assembly assembly)
|
||||
{
|
||||
return assembly.GetName() == Assembly.GetEntryAssembly()?.GetName();
|
||||
return assembly.Equals(Assembly.GetEntryAssembly());
|
||||
}
|
||||
|
||||
internal virtual Stream GetResourceStream(Assembly assembly, string name)
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace Microsoft.DotNet.Tests
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var appDirectory = Path.Combine(_desktopTestProjectsRoot, "AppWithDirectDependencyDesktopAndPortable");
|
||||
|
||||
new BuildCommand(Path.Combine(appDirectory, "project.json"))
|
||||
|
@ -71,6 +71,17 @@ namespace Microsoft.DotNet.Tests
|
|||
result.Should().Pass();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ToolsCanAccessDependencyContextProperly()
|
||||
{
|
||||
var appDirectory = Path.Combine(_testProjectsRoot, "DependencyContextFromTool");
|
||||
|
||||
CommandResult result = new DependencyContextTestCommand() { WorkingDirectory = appDirectory }
|
||||
.Execute(Path.Combine(appDirectory, "project.json"));
|
||||
|
||||
result.Should().Pass();
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> DependencyToolArguments
|
||||
{
|
||||
get
|
||||
|
@ -152,6 +163,26 @@ namespace Microsoft.DotNet.Tests
|
|||
}
|
||||
}
|
||||
|
||||
class DependencyContextTestCommand : TestCommand
|
||||
{
|
||||
public DependencyContextTestCommand()
|
||||
: base("dotnet")
|
||||
{
|
||||
}
|
||||
|
||||
public override CommandResult Execute(string path)
|
||||
{
|
||||
var args = $"dependency-context-test {path}";
|
||||
return base.Execute(args);
|
||||
}
|
||||
|
||||
public override CommandResult ExecuteWithCapturedOutput(string path)
|
||||
{
|
||||
var args = $"dependency-context-test {path}";
|
||||
return base.ExecuteWithCapturedOutput(args);
|
||||
}
|
||||
}
|
||||
|
||||
class DependencyToolInvokerCommand : TestCommand
|
||||
{
|
||||
public DependencyToolInvokerCommand()
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
"../../TestAssets/TestProjects/AppWithDirectAndToolDependency/**/*",
|
||||
"../../TestAssets/TestProjects/AppWithDirectDependency/**/*",
|
||||
"../../TestAssets/TestProjects/AppWithToolDependency/**/*",
|
||||
"../../TestAssets/TestProjects/DependencyContextFromTool/**/*",
|
||||
"../../TestAssets/DesktopTestProjects/AppWithDirectDependencyDesktopAndPortable/**/*"
|
||||
],
|
||||
"testRunner": "xunit"
|
||||
|
|
Loading…
Reference in a new issue