1 //---------------------------------------------------------------------
2 // <copyright file="MetadataAssemblyHelper.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
10 using System.Reflection;
11 using System.Collections.Generic;
12 using System.Diagnostics;
13 using System.Data.Common.Utils;
15 namespace System.Data.Metadata.Edm
17 internal static class MetadataAssemblyHelper
19 static byte [] EcmaPublicKeyToken = System.Data.EntityModel.SchemaObjectModel.ScalarType.ConvertToByteArray(AssemblyRef.EcmaPublicKey);
20 static byte [] MsPublicKeyToken = System.Data.EntityModel.SchemaObjectModel.ScalarType.ConvertToByteArray(AssemblyRef.MicrosoftPublicKey);
21 private static Memoizer<Assembly, bool> _filterAssemblyCacheByAssembly = new Memoizer<Assembly, bool>(MetadataAssemblyHelper.ComputeShouldFilterAssembly, EqualityComparer<Assembly>.Default);
23 internal static Assembly SafeLoadReferencedAssembly(AssemblyName assemblyName)
25 Assembly assembly = null;
29 assembly = Assembly.Load(assemblyName);
31 catch (System.IO.FileNotFoundException)
33 // See 552932: ObjectItemCollection: fails on referenced assemblies that are not available
39 private static bool ComputeShouldFilterAssembly(Assembly assembly)
41 AssemblyName assemblyName = new AssemblyName(assembly.FullName);
42 return ShouldFilterAssembly(assemblyName);
45 internal static bool ShouldFilterAssembly(Assembly assembly)
47 return _filterAssemblyCacheByAssembly.Evaluate(assembly);
50 /// <summary>Is the assembly and its referened assemblies not expected to have any metadata</summary>
51 private static bool ShouldFilterAssembly(AssemblyName assemblyName)
53 return (ArePublicKeyTokensEqual(assemblyName.GetPublicKeyToken(), EcmaPublicKeyToken) ||
54 ArePublicKeyTokensEqual(assemblyName.GetPublicKeyToken(), MsPublicKeyToken));
57 private static bool ArePublicKeyTokensEqual(byte [] left, byte [] right)
59 // some assemblies don't have public keys
60 if (left.Length != right.Length)
65 for (int i = 0; i < left.Length; i++)
67 if (left[i] != right[i])
75 internal static IEnumerable<Assembly> GetNonSystemReferencedAssemblies(Assembly assembly)
77 foreach (AssemblyName name in assembly.GetReferencedAssemblies())
79 if (!ShouldFilterAssembly(name))
81 Assembly referenceAssembly = SafeLoadReferencedAssembly(name);
82 if(referenceAssembly != null )
84 yield return referenceAssembly;