Skip to content

Commit 4300de4

Browse files
rainersigwaldarturcic
authored andcommitted
Return the task assembly from its context in GitLoaderContext
When MSBuild invokes a task from GitVersionTask.MsBuild, it creates an AssemblyLoadContext and loads GitVersionTask into it, then tries to load the type GitVersion.MSBuildTask.GitVersionTasks. The resulting type is then reflected over and a delegate is constructed to call the method inside the loaded type. However, if the task is loaded in its own AssemblyLoadContext, as it is in MSBuild 16.5+ on .NET Core, the types do not match between: 1. The WriteVersionInfoToBuildLog loaded in the task ALC (used in the cast), and 2. The WriteVersionInfoToBuildLog loaded in the GitLoaderContext (returned by reflection). This throws a runtime error. It worked in earlier versions of MSBuild because GitVersionTask.MsBuild was loaded in the default ALC by the MSBuild engine and found in the default ALC by the GetType() call. Change GitLoaderContext so that it returns the currently-loaded entry-point assembly when trying to load that assembly's identity. This works in older MSBuild, because it'll return the default ALC's instance of the type, and in newer MSBuild, because it'll return the task ALC's instance--in both cases accurately reflecting the task's view of the world.
1 parent 1edc517 commit 4300de4

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

src/GitVersionTask.MsBuild/LibGit2Sharp/GitLoaderContext.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,20 @@ namespace GitVersion.MSBuildTask.LibGit2Sharp
1111
{
1212
public sealed class GitLoaderContext : AssemblyLoadContext
1313
{
14+
private readonly Assembly entryPointAssembly;
1415
public static GitLoaderContext Instance { get; private set; }
1516

16-
public static void Init() => Instance = new GitLoaderContext();
17+
private GitLoaderContext(Assembly entryPointAssembly) => this.entryPointAssembly = entryPointAssembly;
18+
19+
public static void Init(Assembly entryPointAssembly) => Instance = new GitLoaderContext(entryPointAssembly);
1720

1821
protected override Assembly Load(AssemblyName assemblyName)
1922
{
23+
if (assemblyName.Name == entryPointAssembly.GetName().Name)
24+
{
25+
return entryPointAssembly;
26+
}
27+
2028
var path = Path.Combine(Path.GetDirectoryName(typeof(GitLoaderContext).Assembly.Location), assemblyName.Name + ".dll");
2129

2230
if (File.Exists(path))

src/GitVersionTask.MsBuild/TaskProxy.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ static TaskProxy()
1818
try
1919
{
2020
#if !NETFRAMEWORK
21-
GitLoaderContext.Init();
21+
GitLoaderContext.Init(typeof(TaskProxy).Assembly);
2222
#endif
2323
LibGit2SharpLoader.LoadAssembly("GitVersionTask");
2424

0 commit comments

Comments
 (0)