예제 #1
0
        // this code is borrowed from XamlSchemaContext
        internal static bool AssemblySatisfiesReference(AssemblyName assemblyName, AssemblyName reference)
        {
            if (reference.Name != assemblyName.Name)
            {
                return(false);
            }

            if (reference.Version != null && !reference.Version.Equals(assemblyName.Version))
            {
                return(false);
            }

            if (reference.CultureInfo != null && !reference.CultureInfo.Equals(assemblyName.CultureInfo))
            {
                return(false);
            }

            byte[] requiredToken = reference.GetPublicKeyToken();
            if (requiredToken != null)
            {
                byte[] actualToken = assemblyName.GetPublicKeyToken();
                if (!AssemblyNameEqualityComparer.IsSameKeyToken(requiredToken, actualToken))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #2
0
        internal static Assembly GetAssembly(AssemblyName assemblyName)
        {
            // the following assembly resolution logic
            // emulates the Xaml's assembly resolution logic as closely as possible.
            // Should Xaml's assembly resolution logic ever change, this code needs update as well.
            // please see XamlSchemaContext.ResolveAssembly()
            if (assemblyCache == null)
            {
                lock (s_assemblyCacheLock)
                {
                    if (assemblyCache == null)
                    {
                        assemblyCache = new Hashtable(AssemblyCacheInitialSize, new AssemblyNameEqualityComparer());
                    }
                }
            }

            Assembly assembly = assemblyCache[assemblyName] as Assembly;

            if (assembly != null)
            {
                return(assembly);
            }

            // search current AppDomain first
            // this for-loop part is to ensure that
            // loose AssemblyNames get resolved in the same way
            // as Xaml would do.  that is to find the first match
            // found starting from the end of the array of Assemblies
            // returned by AppDomain.GetAssemblies()
            Assembly[] currentAssemblies = AppDomain.CurrentDomain.GetAssemblies();
            for (int i = currentAssemblies.Length - 1; i >= 0; i--)
            {
                Assembly curAsm = currentAssemblies[i];
                if (curAsm.IsDynamic)
                {
                    // ignore dynamic assemblies
                    continue;
                }

                AssemblyName curAsmName  = GetFastAssemblyName(curAsm);
                Version      curVersion  = curAsmName.Version;
                CultureInfo  curCulture  = curAsmName.CultureInfo;
                byte[]       curKeyToken = curAsmName.GetPublicKeyToken();

                Version     reqVersion  = assemblyName.Version;
                CultureInfo reqCulture  = assemblyName.CultureInfo;
                byte[]      reqKeyToken = assemblyName.GetPublicKeyToken();

                if ((String.Compare(curAsmName.Name, assemblyName.Name, StringComparison.OrdinalIgnoreCase) == 0) &&
                    (reqVersion == null || reqVersion.Equals(curVersion)) &&
                    (reqCulture == null || reqCulture.Equals(curCulture)) &&
                    (reqKeyToken == null || AssemblyNameEqualityComparer.IsSameKeyToken(reqKeyToken, curKeyToken)))
                {
                    lock (s_assemblyCacheLock)
                    {
                        assemblyCache[assemblyName] = curAsm;
                        return(curAsm);
                    }
                }
            }

            assembly = LoadAssembly(assemblyName);
            if (assembly != null)
            {
                lock (s_assemblyCacheLock)
                {
                    assemblyCache[assemblyName] = assembly;
                }
            }

            return(assembly);
        }