1 //---------------------------------------------------------------------
2 // <copyright file="DefaultAssemblyResolver.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
10 using System.Reflection;
12 using System.Diagnostics;
13 using System.Collections.Generic;
15 using System.Collections;
17 namespace System.Data.Metadata.Edm
19 internal class DefaultAssemblyResolver : MetadataArtifactAssemblyResolver
21 internal override bool TryResolveAssemblyReference(AssemblyName refernceName, out Assembly assembly)
23 assembly = ResolveAssembly(refernceName);
24 return assembly != null;
28 internal override IEnumerable<Assembly> GetWildcardAssemblies()
30 return GetAllDiscoverableAssemblies();
33 internal Assembly ResolveAssembly(AssemblyName referenceName)
35 Assembly assembly = null;
37 // look in the already loaded assemblies
38 foreach (Assembly current in GetAlreadyLoadedNonSystemAssemblies())
40 if (AssemblyName.ReferenceMatchesDefinition(referenceName, new AssemblyName(current.FullName)))
46 // try to load this one specifically
49 assembly = MetadataAssemblyHelper.SafeLoadReferencedAssembly(referenceName);
56 // try all the discoverable ones
57 TryFindWildcardAssemblyMatch(referenceName, out assembly);
62 private bool TryFindWildcardAssemblyMatch(AssemblyName referenceName, out Assembly assembly)
64 Debug.Assert(referenceName != null);
66 foreach (Assembly current in GetAllDiscoverableAssemblies())
68 if (AssemblyName.ReferenceMatchesDefinition(referenceName, new AssemblyName(current.FullName)))
81 /// Return all assemblies loaded in the current AppDomain that are not signed
82 /// with the Microsoft Key.
84 /// <returns>A list of assemblies</returns>
85 private static IEnumerable<Assembly> GetAlreadyLoadedNonSystemAssemblies()
87 Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
88 return assemblies.Where(a => a != null && !MetadataAssemblyHelper.ShouldFilterAssembly(a));
92 /// This method returns a list of assemblies whose contents depend on whether we
93 /// are running in an ASP.NET environment. If we are indeed in a Web/ASP.NET
94 /// scenario, we pick up the assemblies that all page compilations need to
95 /// reference. If not, then we simply get the list of assemblies referenced by
96 /// the entry assembly.
98 /// <returns>A list of assemblies</returns>
99 private static IEnumerable<Assembly> GetAllDiscoverableAssemblies()
101 Assembly assembly = Assembly.GetEntryAssembly();
102 HashSet<Assembly> assemblyList = new HashSet<Assembly>(
103 AssemblyComparer.Instance);
105 foreach (Assembly loadedAssembly in GetAlreadyLoadedNonSystemAssemblies())
107 assemblyList.Add(loadedAssembly);
110 AspProxy aspProxy = new AspProxy();
111 if (!aspProxy.IsAspNetEnvironment())
113 if (assembly == null)
118 assemblyList.Add(assembly);
120 foreach (Assembly referenceAssembly in MetadataAssemblyHelper.GetNonSystemReferencedAssemblies(assembly))
122 assemblyList.Add(referenceAssembly);
128 if (aspProxy.HasBuildManagerType())
130 IEnumerable<Assembly> referencedAssemblies = aspProxy.GetBuildManagerReferencedAssemblies();
131 // filter out system assemblies
132 if (referencedAssemblies != null)
134 foreach (Assembly referencedAssembly in referencedAssemblies)
136 if (MetadataAssemblyHelper.ShouldFilterAssembly(referencedAssembly))
141 assemblyList.Add(referencedAssembly);
146 return assemblyList.Where(a => a != null);
149 internal sealed class AssemblyComparer : IEqualityComparer<Assembly>
152 private AssemblyComparer() { }
154 private static AssemblyComparer _instance = new AssemblyComparer();
155 public static AssemblyComparer Instance{ get { return _instance; } }
158 /// if two assemblies have the same full name, we will consider them as the same.
160 /// both of x and y have the full name as "{RES, Version=3.5.0.0, Culture=neutral, PublicKeyToken=null}",
161 /// although they are different instances since the ReflectionOnly field in them are different, we sitll
162 /// consider them as the same.
164 /// <param name="x"></param>
165 /// <param name="y"></param>
166 /// <returns></returns>
167 public bool Equals(Assembly x, Assembly y)
169 AssemblyName xname = new AssemblyName(x.FullName);
170 AssemblyName yname = new AssemblyName(y.FullName);
171 // return *true* when either the reference are the same
172 // *or* the Assembly names are commutative equal
173 return object.ReferenceEquals(x, y)
174 || (AssemblyName.ReferenceMatchesDefinition(xname, yname)
175 && AssemblyName.ReferenceMatchesDefinition(yname, xname));
178 public int GetHashCode(Assembly assembly)
180 return assembly.FullName.GetHashCode();