public static void LoadInDefaultContext()
        {
            Init();

            // This will attempt to load an assembly, by path, in the Default Load context via the Resolving event
            var assemblyNameStr = "System.Runtime.Loader.Noop.Assembly";
            var assemblyName = new AssemblyName(assemblyNameStr);

            // By default, the assembly should not be found in DefaultContext at all
            Assert.Throws(typeof(FileNotFoundException), () => Assembly.Load(assemblyName));

            // Create a secondary load context and wireup its resolving event
            SecondaryLoadContext slc = new SecondaryLoadContext();
            slc.Resolving += ResolveAssembly;
            
            // Attempt to load the assembly in secondary load context
            var slcLoadedAssembly = slc.LoadFromAssemblyName(assemblyName);
            
            // We should have successfully loaded the assembly in default context.
            Assert.NotNull(slcLoadedAssembly);

            // And make sure the simple name matches
            Assert.Equal(assemblyNameStr, slcLoadedAssembly.GetName().Name);

            // We should have only invoked non-Null returning handler once
            Assert.Equal(1, s_NumNonNullResolutions);

            slc.Resolving -= ResolveAssembly;

            // Reset the non-Null resolution counter
            s_NumNonNullResolutions = 0;

            // Now, wireup the Resolving event of default context to locate the assembly via multiple handlers
            AssemblyLoadContext.Default.Resolving += ResolveNullAssembly;
            AssemblyLoadContext.Default.Resolving += ResolveAssembly;
            AssemblyLoadContext.Default.Resolving += ResolveAssemblyAgain;
            
            // This will invoke the resolution via VM requiring to bind using the TPA binder
            var assemblyExpectedFromLoad = Assembly.Load(assemblyName);

            // We should have successfully loaded the assembly in default context.
            Assert.NotNull(assemblyExpectedFromLoad);

            // We should have only invoked non-Null returning handler once
            Assert.Equal(1, s_NumNonNullResolutions);

            // And make sure the simple name matches
            Assert.Equal(assemblyNameStr, assemblyExpectedFromLoad.GetName().Name);

            // The assembly loaded in DefaultContext should have a different reference from the one in secondary load context
            Assert.NotEqual(slcLoadedAssembly, assemblyExpectedFromLoad);

            // This will resolve the assembly via event invocation.
            var assemblyExpected = AssemblyLoadContext.Default.LoadFromAssemblyName(assemblyName);
            
            // We should have successfully loaded the assembly in default context.
            Assert.NotNull(assemblyExpected);

            // What we got via Assembly.Load and LoadFromAssemblyName should be the same
            Assert.Equal(assemblyExpected, assemblyExpectedFromLoad);

            // And make sure the simple name matches
            Assert.Equal(assemblyExpected.GetName().Name, assemblyNameStr);

            // Unwire the Resolving event.
            AssemblyLoadContext.Default.Resolving -= ResolveAssemblyAgain;
            AssemblyLoadContext.Default.Resolving -= ResolveAssembly;
            AssemblyLoadContext.Default.Resolving -= ResolveNullAssembly;

            // Unwire the Resolving event and attempt to load the assembly again. This time
            // it should be found in the Default Load Context.
            var assemblyLoaded = Assembly.Load(new AssemblyName(assemblyNameStr));

            // We should have successfully found the assembly in default context.
            Assert.NotNull(assemblyLoaded);

            // Ensure that we got the same assembly reference back.
            Assert.Equal(assemblyExpected, assemblyLoaded);

            // Run tests for binding from DefaultContext when custom load context does not have TPA overrides.
            DefaultContextFallback();

            // Run tests for overriding DefaultContext when custom load context has TPA overrides.
            DefaultContextOverrideTPA();
        }
        public void LoadInDefaultContext()
        {
            // This will attempt to load an assembly, by path, in the Default Load context via the Resolving event
            var assemblyName = new AssemblyName(TestAssemblyName);

            // By default, the assembly should not be found in DefaultContext at all
            Assert.Throws(typeof(FileNotFoundException), () => Assembly.Load(assemblyName));

            // Create a secondary load context and wireup its resolving event
            SecondaryLoadContext slc = new SecondaryLoadContext();

            slc.Resolving += ResolveAssembly;

            Assert.Contains(slc, AssemblyLoadContext.All);

            // Attempt to load the assembly in secondary load context
            var slcLoadedAssembly = slc.LoadFromAssemblyName(assemblyName);

            // We should have successfully loaded the assembly in secondary load context.
            Assert.NotNull(slcLoadedAssembly);
            Assert.Contains(slcLoadedAssembly, slc.Assemblies);

            // And make sure the simple name matches
            Assert.Equal(TestAssemblyName, slcLoadedAssembly.GetName().Name);

            // We should have only invoked non-Null returning handler once
            Assert.Equal(1, _numNonNullResolutions);

            slc.Resolving -= ResolveAssembly;

            // Reset the non-Null resolution counter
            _numNonNullResolutions = 0;

            // Now, wireup the Resolving event of default context to locate the assembly via multiple handlers
            AssemblyLoadContext.Default.Resolving += ResolveNullAssembly;
            AssemblyLoadContext.Default.Resolving += ResolveAssembly;
            AssemblyLoadContext.Default.Resolving += ResolveAssemblyAgain;

            // This will invoke the resolution via VM requiring to bind using the TPA binder
            var assemblyExpectedFromLoad = Assembly.Load(assemblyName);

            // We should have successfully loaded the assembly in default context.
            Assert.NotNull(assemblyExpectedFromLoad);
            Assert.Contains(assemblyExpectedFromLoad, AssemblyLoadContext.Default.Assemblies);

            // We should have only invoked non-Null returning handler once
            Assert.Equal(1, _numNonNullResolutions);

            // And make sure the simple name matches
            Assert.Equal(TestAssemblyName, assemblyExpectedFromLoad.GetName().Name);

            // The assembly loaded in DefaultContext should have a different reference from the one in secondary load context
            Assert.NotEqual(slcLoadedAssembly, assemblyExpectedFromLoad);

            // Reset the non-Null resolution counter
            _numNonNullResolutions = 0;

            // Since the assembly is already loaded in TPA Binder, we will get that back without invoking any Resolving event handlers
            var assemblyExpected = AssemblyLoadContext.Default.LoadFromAssemblyName(assemblyName);

            Assert.Equal(0, _numNonNullResolutions);

            // We should have successfully loaded the assembly in default context.
            Assert.NotNull(assemblyExpected);

            // What we got via Assembly.Load and LoadFromAssemblyName should be the same
            Assert.Equal(assemblyExpected, assemblyExpectedFromLoad);

            // And make sure the simple name matches
            Assert.Equal(assemblyExpected.GetName().Name, TestAssemblyName);

            // Unwire the Resolving event.
            AssemblyLoadContext.Default.Resolving -= ResolveAssemblyAgain;
            AssemblyLoadContext.Default.Resolving -= ResolveAssembly;
            AssemblyLoadContext.Default.Resolving -= ResolveNullAssembly;

            // Unwire the Resolving event and attempt to load the assembly again. This time
            // it should be found in the Default Load Context.
            var assemblyLoaded = Assembly.Load(new AssemblyName(TestAssemblyName));

            // We should have successfully found the assembly in default context.
            Assert.NotNull(assemblyLoaded);

            // Ensure that we got the same assembly reference back.
            Assert.Equal(assemblyExpected, assemblyLoaded);

            // Run tests for binding from DefaultContext when custom load context does not have TPA overrides.
            DefaultContextFallback();

            // Run tests for overriding DefaultContext when custom load context has TPA overrides.
            DefaultContextOverrideTPA();
        }
        public static void LoadInDefaultContext()
        {
            Init();

            // This will attempt to load an assembly, by path, in the Default Load context via the Resolving event
            var assemblyNameStr = "System.Runtime.Loader.Noop.Assembly";
            var assemblyName    = new AssemblyName(assemblyNameStr);

            // By default, the assembly should not be found in DefaultContext at all
            Assert.Throws(typeof(FileNotFoundException), () => Assembly.Load(assemblyName));

            // Create a secondary load context and wireup its resolving event
            SecondaryLoadContext slc = new SecondaryLoadContext();

            slc.Resolving += ResolveAssembly;

            // Attempt to load the assembly in secondary load context
            var slcLoadedAssembly = slc.LoadFromAssemblyName(assemblyName);

            // We should have successfully loaded the assembly in default context.
            Assert.NotNull(slcLoadedAssembly);

            // And make sure the simple name matches
            Assert.Equal(assemblyNameStr, slcLoadedAssembly.GetName().Name);

            // We should have only invoked non-Null returning handler once
            Assert.Equal(1, s_NumNonNullResolutions);

            slc.Resolving -= ResolveAssembly;

            // Reset the non-Null resolution counter
            s_NumNonNullResolutions = 0;

            // Now, wireup the Resolving event of default context to locate the assembly via multiple handlers
            AssemblyLoadContext.Default.Resolving += ResolveNullAssembly;
            AssemblyLoadContext.Default.Resolving += ResolveAssembly;
            AssemblyLoadContext.Default.Resolving += ResolveAssemblyAgain;

            // This will invoke the resolution via VM requiring to bind using the TPA binder
            var assemblyExpectedFromLoad = Assembly.Load(assemblyName);

            // We should have successfully loaded the assembly in default context.
            Assert.NotNull(assemblyExpectedFromLoad);

            // We should have only invoked non-Null returning handler once
            Assert.Equal(1, s_NumNonNullResolutions);

            // And make sure the simple name matches
            Assert.Equal(assemblyNameStr, assemblyExpectedFromLoad.GetName().Name);

            // The assembly loaded in DefaultContext should have a different reference from the one in secondary load context
            Assert.NotEqual(slcLoadedAssembly, assemblyExpectedFromLoad);

            // This will resolve the assembly via event invocation.
            var assemblyExpected = AssemblyLoadContext.Default.LoadFromAssemblyName(assemblyName);

            // We should have successfully loaded the assembly in default context.
            Assert.NotNull(assemblyExpected);

            // What we got via Assembly.Load and LoadFromAssemblyName should be the same
            Assert.Equal(assemblyExpected, assemblyExpectedFromLoad);

            // And make sure the simple name matches
            Assert.Equal(assemblyExpected.GetName().Name, assemblyNameStr);

            // Unwire the Resolving event.
            AssemblyLoadContext.Default.Resolving -= ResolveAssemblyAgain;
            AssemblyLoadContext.Default.Resolving -= ResolveAssembly;
            AssemblyLoadContext.Default.Resolving -= ResolveNullAssembly;

            // Unwire the Resolving event and attempt to load the assembly again. This time
            // it should be found in the Default Load Context.
            var assemblyLoaded = Assembly.Load(new AssemblyName(assemblyNameStr));

            // We should have successfully found the assembly in default context.
            Assert.NotNull(assemblyLoaded);

            // Ensure that we got the same assembly reference back.
            Assert.Equal(assemblyExpected, assemblyLoaded);

            DefaultContextFallback();
        }