Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AssemblyName.CodeBase stripped from AssemblyName before going to Resolving event handler #59669

Closed
AArnott opened this issue Sep 27, 2021 · 4 comments

Comments

@AArnott
Copy link
Contributor

AArnott commented Sep 27, 2021

On .NET Framework, Assembly.Load(AssemblyName) will consider the value of AssemblyName.CodeBase before failing to load the assembly.
On .NET Core, not only is the CodeBase property ignored, but it's omitted from a copy of the AssemblyName that is given to the AssemblyLoadContext.Resolving event handler, where I had hoped to re-implement the .NET Framework behavior of honoring that property.

For backwards compatibility when an app migrates from NetFX to .NET Core, being able to see the CodeBase property would be useful. Why is it omitted? Would you consider modifying .NET Core to propagate that property when calling the Resolving event handler to give the host more options for finding assemblies?

Repro:

using System;
using System.Reflection;
#if NETCOREAPP
using System.Runtime.Loader;
#endif

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
#if NETCOREAPP
            AssemblyLoadContext.Default.Resolving += ALC_Resolving;
#endif

            AssemblyName an = AssemblyName.GetAssemblyName(@"C:\git\threading\bin\SosThreadingTools\Debug\net472\SosThreadingTools.dll");
#if NETCOREAPP
           // not necessary on net472
           an.CodeBase = @"C:\git\threading\bin\SosThreadingTools\Debug\net472\SosThreadingTools.dll";
#endif

            Assembly a = Assembly.Load(an); // throws on net5.0
            Console.WriteLine("a is not null: " + (a is object));
        }

#if NETCOREAPP
        private static Assembly ALC_Resolving(AssemblyLoadContext arg1, AssemblyName arg2)
        {
            if (!string.IsNullOrEmpty(arg2.CodeBase)) // null on net5.0
            {
                return arg1.LoadFromAssemblyPath(arg2.CodeBase);
            }

            return null;
        }
#endif
    }
}
@dotnet-issue-labeler dotnet-issue-labeler bot added area-AssemblyLoader-coreclr untriaged New issue has not been triaged by the area owner labels Sep 27, 2021
@ghost
Copy link

ghost commented Sep 27, 2021

Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov
See info in area-owners.md if you want to be subscribed.

Issue Details

On .NET Framework, Assembly.Load(AssemblyName) will consider the value of AssemblyName.CodeBase before failing to load the assembly.
On .NET Core, not only is the CodeBase property ignored, but it's omitted from a copy of the AssemblyName that is given to the AssemblyLoadContext.Resolving event handler, where I had hoped to re-implement the .NET Framework behavior of honoring that property.

For backwards compatibility when an app migrates from NetFX to .NET Core, being able to see the CodeBase property would be useful. Why is it omitted? Would you consider modifying .NET Core to propagate that property when calling the Resolving event handler to give the host more options for finding assemblies?

Repro:

using System;
using System.Reflection;
#if NETCOREAPP
using System.Runtime.Loader;
#endif

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
#if NETCOREAPP
            AssemblyLoadContext.Default.Resolving += ALC_Resolving;
#endif

            AssemblyName an = AssemblyName.GetAssemblyName(@"C:\git\threading\bin\SosThreadingTools\Debug\net472\SosThreadingTools.dll");
            an.CodeBase = @"C:\git\threading\bin\SosThreadingTools\Debug\net472\SosThreadingTools.dll";

            Assembly a = Assembly.Load(an); // net472 succeeds. net5 fails.
        }

#if NETCOREAPP
        private static Assembly ALC_Resolving(AssemblyLoadContext arg1, AssemblyName arg2)
        {
            if (!string.IsNullOrEmpty(arg2.CodeBase)) // net5 sees this as null
            {
                return arg1.LoadFromAssemblyPath(arg2.CodeBase);
            }

            return null;
        }
#endif
    }
}
Author: AArnott
Assignees: -
Labels:

area-AssemblyLoader-coreclr, untriaged

Milestone: -

@jkotas
Copy link
Member

jkotas commented Sep 27, 2021

#7752 has some context

@AArnott
Copy link
Contributor Author

AArnott commented Sep 27, 2021

Thanks for the context. I get that .NET Core wants to diverge in assembly load behavior from Framework. I would like to see the Codebase property preserved in the Resolving event just so an app can choose to re-implement Framework behavior. Right now, it appears to be impossible.

@agocke agocke added this to the 7.0.0 milestone Sep 27, 2021
@agocke agocke removed the untriaged New issue has not been triaged by the area owner label Sep 27, 2021
@agocke agocke added this to AppModel Jun 14, 2022
@agocke agocke modified the milestones: 7.0.0, Future Jul 6, 2022
@agocke
Copy link
Member

agocke commented Jul 26, 2023

We now have precedent from ProcessorArchitecture that we don't preserve obsolete information moving through AssemblyName. CodeBase is in the same category. Closing as Won't Fix.

@agocke agocke closed this as not planned Won't fix, can't repro, duplicate, stale Jul 26, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Aug 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Archived in project
Development

No branches or pull requests

3 participants