Repository: dotnet/runtime
File: src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs (C#)

Code before:

        private RuntimeAssembly? ResolveUsingLoad(AssemblyName assemblyName)
        {
            string? simpleName = assemblyName.Name;

            Assembly? assembly = Load(assemblyName);

            return (assembly != null) ? ValidateAssemblyNameWithSimpleName(assembly, simpleName) : null;
        }

        private RuntimeAssembly? ResolveUsingEvent(AssemblyName assemblyName)
        {
            string? simpleName = assemblyName.Name;

            // Invoke the Resolving event callbacks if wired up
            Assembly? assembly = GetFirstResolvedAssemblyFromResolvingEvent(assemblyName);

            return (assembly != null) ? ValidateAssemblyNameWithSimpleName(assembly, simpleName) : null;
        }

        private static void OnAssemblyLoad(RuntimeAssembly assembly)
        {
            AssemblyLoad?.Invoke(AppDomain.CurrentDomain, new AssemblyLoadEventArgs(assembly));
        }

        internal static RuntimeAssembly? OnResourceResolve(RuntimeAssembly assembly, string resourceName)
        {
            return InvokeResolveEvent(ResourceResolve, assembly, resourceName);
        }

        internal static RuntimeAssembly? OnTypeResolve(RuntimeAssembly? assembly, string typeName)
        {
            return InvokeResolveEvent(TypeResolve, assembly, typeName);
        }

        private static RuntimeAssembly? OnAssemblyResolve(RuntimeAssembly? assembly, string assemblyFullName)
        {
            return InvokeResolveEvent(AssemblyResolve, assembly, assemblyFullName);
        }

        internal static void InvokeAssemblyLoadEvent(Assembly assembly)
        {
            AssemblyLoad?.Invoke(AppDomain.CurrentDomain, new AssemblyLoadEventArgs(assembly));
        }

        [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
            Justification = "The code handles the Assembly.Location equals null")]
        private static RuntimeAssembly? InvokeResolveEvent(ResolveEventHandler? eventHandler, RuntimeAssembly? assembly, string name)
        {
            if (eventHandler == null)
                return null;

Review comment (refactor):
The `OnResourceResolve` method accepts a non-nullable `RuntimeAssembly assembly` parameter, but the native caller in `AppDomain::RaiseResourceResolveEvent` (appdomain.cpp:3712-3713) can pass a null assembly reference. The UnmanagedCallersOnly wrapper dereferences the pointer unconditionally and passes the result to the method.

While this issue also existed in the previous `MethodDescCallSite`-based implementation, it would be beneficial to fix it during this refactoring. The method signature should be changed to accept nullable RuntimeAssembly, matching the pattern used in `OnTypeResolve` and `OnAssemblyResolve`.
```suggestion
        internal static RuntimeAssembly? OnResourceResolve(RuntimeAssembly? assembly, string resourceName)
```

Code after:
        }

        private RuntimeAssembly? ResolveUsingLoad(AssemblyName assemblyName)
        {
            string? simpleName = assemblyName.Name;

            Assembly? assembly = Load(assemblyName);

            return (assembly != null) ? ValidateAssemblyNameWithSimpleName(assembly, simpleName) : null;
        }

        private RuntimeAssembly? ResolveUsingEvent(AssemblyName assemblyName)
        {
            string? simpleName = assemblyName.Name;

            // Invoke the Resolving event callbacks if wired up
            Assembly? assembly = GetFirstResolvedAssemblyFromResolvingEvent(assemblyName);

            return (assembly != null) ? ValidateAssemblyNameWithSimpleName(assembly, simpleName) : null;
        }

        private static void OnAssemblyLoad(RuntimeAssembly assembly)
        {
            AssemblyLoad?.Invoke(AppDomain.CurrentDomain, new AssemblyLoadEventArgs(assembly));
        }

        internal static RuntimeAssembly? OnResourceResolve(RuntimeAssembly? assembly, string resourceName)
        {
            return InvokeResolveEvent(ResourceResolve, assembly, resourceName);
        }

        internal static RuntimeAssembly? OnTypeResolve(RuntimeAssembly? assembly, string typeName)
        {
            return InvokeResolveEvent(TypeResolve, assembly, typeName);
        }

        private static RuntimeAssembly? OnAssemblyResolve(RuntimeAssembly? assembly, string assemblyFullName)
        {
            return InvokeResolveEvent(AssemblyResolve, assembly, assemblyFullName);
        }

        internal static void InvokeAssemblyLoadEvent(Assembly assembly)
        {
            AssemblyLoad?.Invoke(AppDomain.CurrentDomain, new AssemblyLoadEventArgs(assembly));
        }

        [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
            Justification = "The code handles the Assembly.Location equals null")]
        private static RuntimeAssembly? InvokeResolveEvent(ResolveEventHandler? eventHandler, RuntimeAssembly? assembly, string name)
        {
            if (eventHandler == null)