// Copyright (c) Microsoft Corporation. All rights reserved.
//
using System;
using System.Collections.Generic;
using System.Xml.XPath;
using System.Compiler;
namespace Microsoft.Ddue.Tools.Reflection{
public class AssemblyResolver {
private Dictionary < string, AssemblyNode > cache = new Dictionary < string, AssemblyNode >();
private bool useGac = true;
public AssemblyResolver() {
}
public AssemblyResolver(XPathNavigator configuration) {
string useGacValue = configuration.GetAttribute("use-gac", String.Empty);
if (!String.IsNullOrEmpty(useGacValue)) useGac = Convert.ToBoolean(useGacValue);
}
public event EventHandler < AssemblyReferenceEventArgs > UnresolvedAssemblyReference;
public bool UseGac {
get {
return (useGac);
}
set {
useGac = value;
}
}
public virtual void Add(AssemblyNode assembly) {
if (assembly == null) throw new ArgumentNullException("assembly");
string name = assembly.StrongName;
assembly.AssemblyReferenceResolution += new Module.AssemblyReferenceResolver(ResolveReference);
assembly.AssemblyReferenceResolutionAfterProbingFailed += new Module.AssemblyReferenceResolver(UnresolvedReference);
cache[name] = assembly;
//Console.WriteLine("added {0}; cache now contains {1}", name, cache.Count);
}
public virtual AssemblyNode ResolveReference(AssemblyReference reference, Module module) {
if (reference == null) throw new ArgumentNullException("reference");
//Console.WriteLine("resolving {0}", reference.StrongName);
// try to get it from the cache
string name = reference.StrongName;
if (cache.ContainsKey(name)) return (cache[name]);
// try to get it from the gac
if (useGac) {
string location = GlobalAssemblyCache.GetLocation(reference);
if (location != null) {
AssemblyNode assembly = AssemblyNode.GetAssembly(location, null, false, false, false, false);
if (assembly != null) {
Add(assembly);
return (assembly);
}
}
}
// couldn't find it; return null
// Console.WriteLine("returning null on request for {0}", reference.StrongName);
//OnUnresolvedAssemblyReference(reference, module);
return (null);
}
protected virtual void OnUnresolvedAssemblyReference(AssemblyReference reference, Module module) {
if (UnresolvedAssemblyReference != null) UnresolvedAssemblyReference(this, new AssemblyReferenceEventArgs(reference, module));
}
private AssemblyNode UnresolvedReference(AssemblyReference reference, Module module) {
OnUnresolvedAssemblyReference(reference, module);
return (null);
}
}
}
|