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