PageRenderTime 7ms CodeModel.GetById 1ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/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}