Example #1
0
        public static void CoreAssemblyCanBeAFacade()
        {
            Assembly actualCoreAssembly = null;
            Assembly testAssembly       = null;

            var resolver = new FuncMetadataAssemblyResolver(
                delegate(MetadataLoadContext context, AssemblyName refName)
            {
                if (refName.Name.Equals("mscorlib", StringComparison.OrdinalIgnoreCase))
                {
                    return(actualCoreAssembly = context.LoadFromStream(TestUtils.CreateStreamForCoreAssembly()));
                }
                //else if (refName.Equals(new AssemblyName(TestData.s_PhonyCoreAssemblyName)))
                else if (refName.Name == new AssemblyName(TestData.s_PhonyCoreAssemblyName).Name)
                {
                    return(testAssembly = context.LoadFromByteArray(TestData.s_PhonyCoreAssemblyImage));
                }
                return(null);
            });

            using (MetadataLoadContext lc = new MetadataLoadContext(resolver, coreAssemblyName: TestData.s_PhonyCoreAssemblyName))
            {
                // This is a sanity check to ensure that "TestData.s_PhonyCoreAssemblyName" is actually the def-name of this
                // assembly. It better be since we told our MetadataLoadContext to use it as our core assembly.
                Assembly aAgain = lc.LoadFromAssemblyName(TestData.s_PhonyCoreAssemblyName);

                Type derived = testAssembly.GetType("Derived", throwOnError: true, ignoreCase: false);

                // Calling BaseType causes the MetadataLoadContext to parse the typespec "Base<object>". Since "object" is a primitive
                // type, it should be encoded using the short-form "ELEMENT_TYPE_OBJECT." Hence, the MetadataLoadContext is forced
                // to look up "System.Object" in the core assembly we assigned to it, which in this case is "PhonyCoreAssembly"
                // which type-forwards System.Object to "mscorlib".
                Type baseType = derived.BaseType;

                Assert.NotNull(actualCoreAssembly); // Ensure our resolve handler actually ran.
                Assert.NotEqual(testAssembly, actualCoreAssembly);
                Assert.True(baseType.IsConstructedGenericType);
                Type retrievedObjectType = baseType.GenericTypeArguments[0];
                Assert.Equal("System.Object", retrievedObjectType.FullName);
                Assert.Equal(actualCoreAssembly, retrievedObjectType.Assembly);
            }
        }
Example #2
0
        public static void ResolverFromReferencedAssembliesUsingFullPublicKeyReference()
        {
            // Ecma-335 allows an assembly reference to specify a full public key rather than the token. Ensure that those references
            // still hand out usable AssemblyNames to resolve handlers.

            AssemblyName assemblyNameReceivedByHandler = null;

            var resolver = new FuncMetadataAssemblyResolver(
                delegate(MetadataLoadContext context, AssemblyName name)
            {
                if (name.Name == "RedirectCore")
                {
                    return(context.LoadFromByteArray(TestData.s_SimpleNameOnlyImage));
                }

                assemblyNameReceivedByHandler = name;
                return(null);
            });

            using (MetadataLoadContext lc = new MetadataLoadContext(resolver, "RedirectCore"))
            {
                Assembly a = lc.LoadFromByteArray(TestData.s_AssemblyRefUsingFullPublicKeyImage);
                Type     t = a.GetType("C", throwOnError: true);

                // We expect this next to call to throw since it asks the MetadataLoadContext to resolve [mscorlib]System.Object and our
                // resolve handler doesn't return anything for that.
                Assert.Throws <FileNotFoundException> (() => t.BaseType);

                // But it did get called with a request to resolve "mscorlib" and we got the correct PKT calculated from the PK.
                // Note that the original PK is not made available (which follows prior precedent with these apis.) It's not like
                // anyone binds with the full PK...
                Assert.NotNull(assemblyNameReceivedByHandler);
                byte[] expectedPkt = "b77a5c561934e089".HexToByteArray();
                byte[] actualPkt   = assemblyNameReceivedByHandler.GetPublicKeyToken();
                Assert.Equal <byte>(expectedPkt, actualPkt);
            }
        }
Example #3
0
        public static void GetAssemblies_SnapshotIsAtomic()
        {
            Assembly a1 = null;

            var resolver = new FuncMetadataAssemblyResolver(
                delegate(MetadataLoadContext context, AssemblyName refName)
            {
                if (a1 == null)
                {
                    // Initial request to load core assembly
                    return(a1 = context.LoadFromByteArray(TestData.s_SimpleAssemblyImage));
                }
                return(null);
            });

            using (MetadataLoadContext lc = new MetadataLoadContext(resolver))
            {
                IEnumerable <Assembly> loadedAssembliesSnapshot = lc.GetAssemblies();
                Assembly   a2 = lc.LoadFromByteArray(TestData.s_SimpleNameOnlyImage);
                Assembly[] loadedAssemblies = loadedAssembliesSnapshot.ToArray();
                Assert.Equal(1, loadedAssemblies.Length);
                Assert.Equal(a1, loadedAssemblies[0]);
            }
        }
Example #4
0
        public static void ResolverNoUnnecessaryCalls()
        {
            int      resolveHandlerCallCount   = 0;
            Assembly resolveEventHandlerResult = null;

            var resolver = new FuncMetadataAssemblyResolver(
                delegate(MetadataLoadContext context, AssemblyName name)
            {
                if (name.Name == "Foo")
                {
                    resolveHandlerCallCount++;
                    resolveEventHandlerResult = context.LoadFromByteArray(TestData.s_BaseClassesImage);
                    return(resolveEventHandlerResult);
                }

                if (name.Name == "mscorlib")
                {
                    return(context.LoadFromByteArray(TestData.s_SimpleNameOnlyImage));
                }

                return(null);
            });

            // In a single-threaded scenario at least, MetadataLoadContexts shouldn't ask the resolver to bind the same name twice.
            using (MetadataLoadContext lc = new MetadataLoadContext(resolver))
            {
                Assembly derived = lc.LoadFromByteArray(TestData.s_DerivedClassWithVariationsOnFooImage);
                Type     t1      = derived.GetType("Derived1", throwOnError: true);
                Type     bt1     = t1.BaseType;
                Type     t2      = derived.GetType("Derived2", throwOnError: true);
                Type     bt2     = t2.BaseType;
                Assert.Equal(1, resolveHandlerCallCount);
                Assert.Equal(resolveEventHandlerResult, bt1.Assembly);
                Assert.Equal(resolveEventHandlerResult, bt2.Assembly);
            }
        }