summaryrefslogtreecommitdiffstats
path: root/tools/Sandcastle/Source/Reflection/AssemblyResolver.cs
blob: 116dcc8c5c68318bdedb4fdbb488ce8e4e9476a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// 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);
        }

    }

}