2010-03-17 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mcs / nunit24 / NUnitCore / core / AssemblyResolver.cs
1 // ****************************************************************\r
2 // This is free software licensed under the NUnit license. You\r
3 // may obtain a copy of the license as well as information regarding\r
4 // copyright ownership at http://nunit.org/?p=license&r=2.4.\r
5 // ****************************************************************\r
6 \r
7 namespace NUnit.Core\r
8 {\r
9         using System;\r
10         using System.IO;\r
11         using System.Reflection;\r
12         using System.Collections;\r
13 \r
14         /// <summary>\r
15         /// Class adapted from NUnitAddin for use in handling assemblies that are not\r
16     /// found in the test AppDomain.\r
17         /// </summary>\r
18     public class AssemblyResolver : MarshalByRefObject, IDisposable\r
19         {\r
20                 private class AssemblyCache\r
21                 {\r
22                         private Hashtable _resolved = new Hashtable();\r
23 \r
24                         public bool Contains( string name )\r
25                         {\r
26                                 return _resolved.ContainsKey( name );\r
27                         }\r
28 \r
29                         public Assembly Resolve( string name )\r
30                         {\r
31                                 if ( _resolved.ContainsKey( name ) )\r
32                                         return (Assembly)_resolved[name];\r
33                                 \r
34                                 return null;\r
35                         }\r
36 \r
37                         public void Add( string name, Assembly assembly )\r
38                         {\r
39                                 _resolved[name] = assembly;\r
40                         }\r
41                 }\r
42 \r
43                 private AssemblyCache _cache = new AssemblyCache();\r
44 \r
45                 private ArrayList _dirs = new ArrayList();\r
46 \r
47                 public AssemblyResolver()\r
48                 {\r
49                         AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);\r
50                 }\r
51 \r
52                 public void Dispose()\r
53                 {\r
54                         AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(CurrentDomain_AssemblyResolve);\r
55                 }\r
56 \r
57                 public void AddFile( string file )\r
58                 {\r
59                         Assembly assembly = Assembly.LoadFrom( file );\r
60                         _cache.Add(assembly.GetName().FullName, assembly);\r
61                 }\r
62 \r
63                 public void AddFiles( string directory, string pattern )\r
64                 {\r
65                         if ( Directory.Exists( directory ) )\r
66                                 foreach( string file in Directory.GetFiles( directory, pattern ) )\r
67                                         AddFile( file );\r
68                 }\r
69 \r
70                 public void AddDirectory( string directory )\r
71                 {\r
72                         if ( Directory.Exists( directory ) )\r
73                                 _dirs.Add( directory );\r
74                 }\r
75 \r
76                 private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)\r
77                 {\r
78                         string fullName = args.Name;\r
79                         int index = fullName.IndexOf(',');\r
80                         if(index == -1)                                                 // Only resolve using full name.\r
81                         {\r
82                                 NTrace.Debug( string.Format("Not a strong name: {0}", fullName ),\r
83                                         "'AssemblyResolver'" );\r
84                                 return null;\r
85                         }\r
86 \r
87                         if ( _cache.Contains( fullName ) )\r
88                         {\r
89                                 NTrace.Info( string.Format( "Resolved from Cache: {0}", fullName ), \r
90                                         "'AssemblyResolver'" );\r
91                                 return _cache.Resolve(fullName);\r
92                         }\r
93 \r
94                         foreach( string dir in _dirs )\r
95                         {\r
96                                 foreach( string file in Directory.GetFiles( dir, "*.dll" ) )\r
97                                 {\r
98                                         string fullFile = Path.Combine( dir, file );\r
99                                         try\r
100                                         {\r
101                                                 if ( AssemblyName.GetAssemblyName( fullFile ).FullName == fullName )\r
102                                                 {\r
103                                                         NTrace.Info( string.Format( "Added to Cache: {0}", fullFile ), \r
104                                                                 "'AssemblyResolver'" );\r
105                                                         AddFile( fullFile );\r
106                                                         return _cache.Resolve( fullName );\r
107                                                 }\r
108                                         }\r
109                                         catch\r
110                                         {\r
111                                                 // Keep going if there's a bad assembly\r
112                                                 NTrace.Debug( string.Format( "Bad assembly: {0}", fullFile  ), "AssemblyResolver");\r
113                                         }\r
114                                 }\r
115                         }\r
116 \r
117                         NTrace.Debug( string.Format( "Not in Cache: {0}", fullName), \r
118                                 "'AssemblyResolver'");\r
119                         return null;\r
120                 }\r
121         }\r
122 }\r