| 
0
 | 
     1 using System;
 | 
| 
 | 
     2 using System.Collections;
 | 
| 
 | 
     3 using System.Collections.Generic;
 | 
| 
 | 
     4 using System.Diagnostics;
 | 
| 
 | 
     5 using System.Diagnostics.CodeAnalysis;
 | 
| 
 | 
     6 using System.IO;
 | 
| 
 | 
     7 using System.Linq.Expressions;
 | 
| 
 | 
     8 using System.Reflection;
 | 
| 
 | 
     9 using System.Reflection.Emit;
 | 
| 
 | 
    10 using System.Runtime.InteropServices;
 | 
| 
 | 
    11 using System.Security;
 | 
| 
 | 
    12 using System.Security.Permissions;
 | 
| 
 | 
    13 
 | 
| 
 | 
    14 using JetBrains.Annotations;
 | 
| 
 | 
    15 
 | 
| 
 | 
    16 using BLToolkit.Reflection;
 | 
| 
 | 
    17 using BLToolkit.Reflection.Emit;
 | 
| 
 | 
    18 using BLToolkit.TypeBuilder.Builders;
 | 
| 
 | 
    19 using BLToolkit.Properties;
 | 
| 
 | 
    20 #if !SILVERLIGHT
 | 
| 
 | 
    21 using BLToolkit.Configuration;
 | 
| 
 | 
    22 #endif
 | 
| 
 | 
    23 
 | 
| 
 | 
    24 namespace BLToolkit.TypeBuilder
 | 
| 
 | 
    25 {
 | 
| 
 | 
    26 	public static class TypeFactory
 | 
| 
 | 
    27 	{
 | 
| 
 | 
    28 		static TypeFactory()
 | 
| 
 | 
    29 		{
 | 
| 
 | 
    30 			SealTypes = true;
 | 
| 
 | 
    31 
 | 
| 
 | 
    32 #if !SILVERLIGHT
 | 
| 
 | 
    33 
 | 
| 
 | 
    34 			var section = BLToolkitSection.Instance;
 | 
| 
 | 
    35 
 | 
| 
 | 
    36 			if (section != null)
 | 
| 
 | 
    37 			{
 | 
| 
 | 
    38 				var elm = section.TypeFactory;
 | 
| 
 | 
    39 
 | 
| 
 | 
    40 				if (elm != null)
 | 
| 
 | 
    41 				{
 | 
| 
 | 
    42 					SaveTypes = elm.SaveTypes;
 | 
| 
 | 
    43 					SealTypes = elm.SealTypes;
 | 
| 
 | 
    44 					LoadTypes = elm.LoadTypes;
 | 
| 
 | 
    45 
 | 
| 
 | 
    46 					SetGlobalAssembly(elm.AssemblyPath, elm.Version, elm.KeyFile);
 | 
| 
 | 
    47 				}
 | 
| 
 | 
    48 			}
 | 
| 
 | 
    49 
 | 
| 
 | 
    50 #endif
 | 
| 
 | 
    51 
 | 
| 
 | 
    52 #if !SILVERLIGHT
 | 
| 
 | 
    53 
 | 
| 
 | 
    54 			var perm = new SecurityPermission(SecurityPermissionFlag.ControlAppDomain);
 | 
| 
 | 
    55 
 | 
| 
 | 
    56 #if FW4
 | 
| 
 | 
    57 			try
 | 
| 
 | 
    58 			{
 | 
| 
 | 
    59 				//var permissionSet = new PermissionSet(PermissionState.None);
 | 
| 
 | 
    60 				//permissionSet.AddPermission(perm);
 | 
| 
 | 
    61 
 | 
| 
 | 
    62 				//if (permissionSet.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet))
 | 
| 
 | 
    63 					SubscribeAssemblyResolver();
 | 
| 
 | 
    64 			}
 | 
| 
 | 
    65 			catch
 | 
| 
 | 
    66 			{
 | 
| 
 | 
    67 			}
 | 
| 
 | 
    68 #else
 | 
| 
 | 
    69 			if (SecurityManager.IsGranted(perm))
 | 
| 
 | 
    70 				SubscribeAssemblyResolver();
 | 
| 
 | 
    71 #endif
 | 
| 
 | 
    72 
 | 
| 
 | 
    73 #endif
 | 
| 
 | 
    74 		}
 | 
| 
 | 
    75 
 | 
| 
 | 
    76 		static void SubscribeAssemblyResolver()
 | 
| 
 | 
    77 		{
 | 
| 
 | 
    78 #if FW4
 | 
| 
 | 
    79 			// This hack allows skipping FW 4.0 security check for partial trusted assemblies.
 | 
| 
 | 
    80 			//
 | 
| 
 | 
    81 
 | 
| 
 | 
    82 			var dm   = new DynamicMethod("SubscribeAssemblyResolverEx", typeof(void), null);
 | 
| 
 | 
    83 			var emit = new EmitHelper(dm.GetILGenerator());
 | 
| 
 | 
    84 
 | 
| 
 | 
    85 			emit
 | 
| 
 | 
    86 				.call     (typeof(AppDomain).GetProperty("CurrentDomain").GetGetMethod())
 | 
| 
 | 
    87 				.ldnull
 | 
| 
 | 
    88 				.ldftn    (typeof(TypeFactory).GetMethod("AssemblyResolver"))
 | 
| 
 | 
    89 				.newobj   (typeof(ResolveEventHandler).GetConstructor(new[] { typeof(object), typeof(IntPtr) }))
 | 
| 
 | 
    90 				.callvirt (typeof(AppDomain).GetEvent("AssemblyResolve").GetAddMethod())
 | 
| 
 | 
    91 				.ret()
 | 
| 
 | 
    92 				;
 | 
| 
 | 
    93 
 | 
| 
 | 
    94 			var setter = (Action)dm.CreateDelegate(typeof(Action));
 | 
| 
 | 
    95 
 | 
| 
 | 
    96 			setter();
 | 
| 
 | 
    97 #else
 | 
| 
 | 
    98 			AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolver;
 | 
| 
 | 
    99 #endif
 | 
| 
 | 
   100 		}
 | 
| 
 | 
   101 
 | 
| 
 | 
   102 		#region Create Assembly
 | 
| 
 | 
   103 
 | 
| 
 | 
   104 		private static string                _globalAssemblyPath;
 | 
| 
 | 
   105 		private static string                _globalAssemblyKeyFile;
 | 
| 
 | 
   106 		private static Version               _globalAssemblyVersion;
 | 
| 
 | 
   107 		private static AssemblyBuilderHelper _globalAssembly;
 | 
| 
 | 
   108 
 | 
| 
 | 
   109 		private static AssemblyBuilderHelper GlobalAssemblyBuilder
 | 
| 
 | 
   110 		{
 | 
| 
 | 
   111 			get
 | 
| 
 | 
   112 			{
 | 
| 
 | 
   113 				if (_globalAssembly == null && _globalAssemblyPath != null)
 | 
| 
 | 
   114 					_globalAssembly = new AssemblyBuilderHelper(_globalAssemblyPath, _globalAssemblyVersion, _globalAssemblyKeyFile);
 | 
| 
 | 
   115 
 | 
| 
 | 
   116 				return _globalAssembly;
 | 
| 
 | 
   117 			}
 | 
| 
 | 
   118 		}
 | 
| 
 | 
   119 
 | 
| 
 | 
   120 		public static bool SaveTypes { get; set; }
 | 
| 
 | 
   121 		public static bool SealTypes { get; set; }
 | 
| 
 | 
   122 
 | 
| 
 | 
   123 		[SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]
 | 
| 
 | 
   124 		public static void SetGlobalAssembly(string path)
 | 
| 
 | 
   125 		{
 | 
| 
 | 
   126 			SetGlobalAssembly(path, null, null);
 | 
| 
 | 
   127 		}
 | 
| 
 | 
   128 
 | 
| 
 | 
   129 		[SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]
 | 
| 
 | 
   130 		public static void SetGlobalAssembly(string path, Version version, string keyFile)
 | 
| 
 | 
   131 		{
 | 
| 
 | 
   132 			if (_globalAssembly != null)
 | 
| 
 | 
   133 				SaveGlobalAssembly();
 | 
| 
 | 
   134 
 | 
| 
 | 
   135 			if (!string.IsNullOrEmpty(path))
 | 
| 
 | 
   136 				_globalAssemblyPath = path;
 | 
| 
 | 
   137 
 | 
| 
 | 
   138 			_globalAssemblyVersion = version;
 | 
| 
 | 
   139 			_globalAssemblyKeyFile = keyFile;
 | 
| 
 | 
   140 		}
 | 
| 
 | 
   141 
 | 
| 
 | 
   142 		public static void SaveGlobalAssembly()
 | 
| 
 | 
   143 		{
 | 
| 
 | 
   144 			if (_globalAssembly != null)
 | 
| 
 | 
   145 			{
 | 
| 
 | 
   146 				_globalAssembly.Save();
 | 
| 
 | 
   147 
 | 
| 
 | 
   148 				WriteDebug("The global assembly saved in '{0}'.", _globalAssembly.Path);
 | 
| 
 | 
   149 
 | 
| 
 | 
   150 				_globalAssembly        = null;
 | 
| 
 | 
   151 				_globalAssemblyPath    = null;
 | 
| 
 | 
   152 				_globalAssemblyVersion = null;
 | 
| 
 | 
   153 				_globalAssemblyKeyFile = null;
 | 
| 
 | 
   154 			}
 | 
| 
 | 
   155 		}
 | 
| 
 | 
   156 
 | 
| 
 | 
   157 		private static AssemblyBuilderHelper GetAssemblyBuilder(Type type, string suffix)
 | 
| 
 | 
   158 		{
 | 
| 
 | 
   159 			var ab = GlobalAssemblyBuilder;
 | 
| 
 | 
   160 
 | 
| 
 | 
   161 			if (ab == null)
 | 
| 
 | 
   162 			{
 | 
| 
 | 
   163 #if SILVERLIGHT
 | 
| 
 | 
   164 				var assemblyDir = ".";
 | 
| 
 | 
   165 #else
 | 
| 
 | 
   166 				var assemblyDir = AppDomain.CurrentDomain.BaseDirectory;
 | 
| 
 | 
   167 
 | 
| 
 | 
   168 				// Dynamic modules are locationless, so ignore them.
 | 
| 
 | 
   169 				// _ModuleBuilder is the base type for both
 | 
| 
 | 
   170 				// ModuleBuilder and InternalModuleBuilder classes.
 | 
| 
 | 
   171 				//
 | 
| 
 | 
   172 				if (!(type.Module is _ModuleBuilder) && type.Module.FullyQualifiedName != null && type.Module.FullyQualifiedName.IndexOf('<') < 0)
 | 
| 
 | 
   173 					assemblyDir = Path.GetDirectoryName(type.Module.FullyQualifiedName);
 | 
| 
 | 
   174 #endif
 | 
| 
 | 
   175 
 | 
| 
 | 
   176 				var fullName = type.FullName;
 | 
| 
 | 
   177 
 | 
| 
 | 
   178 				if (type.IsGenericType)
 | 
| 
 | 
   179 					fullName = AbstractClassBuilder.GetTypeFullName(type);
 | 
| 
 | 
   180 
 | 
| 
 | 
   181 				fullName = fullName.Replace('<', '_').Replace('>', '_');
 | 
| 
 | 
   182 
 | 
| 
 | 
   183 				ab = new AssemblyBuilderHelper(Path.Combine(assemblyDir, fullName + "." + suffix + ".dll"));
 | 
| 
 | 
   184 			}
 | 
| 
 | 
   185 
 | 
| 
 | 
   186 			return ab;
 | 
| 
 | 
   187 		}
 | 
| 
 | 
   188 
 | 
| 
 | 
   189 		[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
 | 
| 
 | 
   190 		private static void SaveAssembly(AssemblyBuilderHelper assemblyBuilder, Type type)
 | 
| 
 | 
   191 		{
 | 
| 
 | 
   192 			if (!SaveTypes || _globalAssembly != null)
 | 
| 
 | 
   193 				return;
 | 
| 
 | 
   194 			try
 | 
| 
 | 
   195 			{
 | 
| 
 | 
   196 				assemblyBuilder.Save();
 | 
| 
 | 
   197 
 | 
| 
 | 
   198 				WriteDebug("The '{0}' type saved in '{1}'.",
 | 
| 
 | 
   199 							type.FullName,
 | 
| 
 | 
   200 							assemblyBuilder.Path);
 | 
| 
 | 
   201 			}
 | 
| 
 | 
   202 			catch (Exception ex)
 | 
| 
 | 
   203 			{
 | 
| 
 | 
   204 				WriteDebug("Can't save the '{0}' assembly for the '{1}' type: {2}.",
 | 
| 
 | 
   205 							assemblyBuilder.Path,
 | 
| 
 | 
   206 							type.FullName,
 | 
| 
 | 
   207 							ex.Message);
 | 
| 
 | 
   208 			}
 | 
| 
 | 
   209 		}
 | 
| 
 | 
   210 
 | 
| 
 | 
   211 		#endregion
 | 
| 
 | 
   212 
 | 
| 
 | 
   213 		#region GetType
 | 
| 
 | 
   214 
 | 
| 
 | 
   215 		static readonly Dictionary<Type,IDictionary<object,Type>> _builtTypes = new Dictionary<Type,IDictionary<object,Type>>(10);
 | 
| 
 | 
   216 		static readonly Dictionary<Assembly,Assembly>             _assemblies = new Dictionary<Assembly, Assembly>(10);
 | 
| 
 | 
   217 
 | 
| 
 | 
   218 		public static bool LoadTypes { get; set; }
 | 
| 
 | 
   219 
 | 
| 
 | 
   220 		public static Type GetType(object hashKey, Type sourceType, ITypeBuilder typeBuilder)
 | 
| 
 | 
   221 		{
 | 
| 
 | 
   222 			if (hashKey     == null) throw new ArgumentNullException("hashKey");
 | 
| 
 | 
   223 			if (sourceType  == null) throw new ArgumentNullException("sourceType");
 | 
| 
 | 
   224 			if (typeBuilder == null) throw new ArgumentNullException("typeBuilder");
 | 
| 
 | 
   225 
 | 
| 
 | 
   226 			try
 | 
| 
 | 
   227 			{
 | 
| 
 | 
   228 				lock (_builtTypes)
 | 
| 
 | 
   229 				{
 | 
| 
 | 
   230 					Type type;
 | 
| 
 | 
   231 					IDictionary<object,Type> builderTable;
 | 
| 
 | 
   232 
 | 
| 
 | 
   233 					if (_builtTypes.TryGetValue(typeBuilder.GetType(), out builderTable))
 | 
| 
 | 
   234 					{
 | 
| 
 | 
   235 						if (builderTable.TryGetValue(hashKey, out type))
 | 
| 
 | 
   236 							return type;
 | 
| 
 | 
   237 					}
 | 
| 
 | 
   238 					else
 | 
| 
 | 
   239 						_builtTypes.Add(typeBuilder.GetType(), builderTable = new Dictionary<object,Type>());
 | 
| 
 | 
   240 
 | 
| 
 | 
   241 					if (LoadTypes)
 | 
| 
 | 
   242 					{
 | 
| 
 | 
   243 						var originalAssembly = sourceType.Assembly;
 | 
| 
 | 
   244 
 | 
| 
 | 
   245 						Assembly extensionAssembly;
 | 
| 
 | 
   246 
 | 
| 
 | 
   247 						if (!_assemblies.TryGetValue(originalAssembly, out extensionAssembly))
 | 
| 
 | 
   248 						{
 | 
| 
 | 
   249 							extensionAssembly = LoadExtensionAssembly(originalAssembly);
 | 
| 
 | 
   250 							_assemblies.Add(originalAssembly, extensionAssembly);
 | 
| 
 | 
   251 						}
 | 
| 
 | 
   252 
 | 
| 
 | 
   253 						if (extensionAssembly != null)
 | 
| 
 | 
   254 						{
 | 
| 
 | 
   255 							type = extensionAssembly.GetType(typeBuilder.GetTypeName());
 | 
| 
 | 
   256 
 | 
| 
 | 
   257 							if (type != null)
 | 
| 
 | 
   258 							{
 | 
| 
 | 
   259 								builderTable.Add(hashKey, type);
 | 
| 
 | 
   260 								return type;
 | 
| 
 | 
   261 							}
 | 
| 
 | 
   262 						}
 | 
| 
 | 
   263 					}
 | 
| 
 | 
   264 
 | 
| 
 | 
   265 					var assemblyBuilder = GetAssemblyBuilder(sourceType, typeBuilder.AssemblyNameSuffix);
 | 
| 
 | 
   266 
 | 
| 
 | 
   267 					type = typeBuilder.Build(assemblyBuilder);
 | 
| 
 | 
   268 
 | 
| 
 | 
   269 					if (type != null)
 | 
| 
 | 
   270 					{
 | 
| 
 | 
   271 						builderTable.Add(hashKey, type);
 | 
| 
 | 
   272 						SaveAssembly(assemblyBuilder, type);
 | 
| 
 | 
   273 					}
 | 
| 
 | 
   274 
 | 
| 
 | 
   275 					return type;
 | 
| 
 | 
   276 				}
 | 
| 
 | 
   277 			}
 | 
| 
 | 
   278 			catch (TypeBuilderException)
 | 
| 
 | 
   279 			{
 | 
| 
 | 
   280 				throw;
 | 
| 
 | 
   281 			}
 | 
| 
 | 
   282 			catch (Exception ex)
 | 
| 
 | 
   283 			{
 | 
| 
 | 
   284 				// Convert an Exception to TypeBuilderException.
 | 
| 
 | 
   285 				//
 | 
| 
 | 
   286 				throw new TypeBuilderException(string.Format(Resources.TypeFactory_BuildFailed, sourceType.FullName), ex);
 | 
| 
 | 
   287 			}
 | 
| 
 | 
   288 		}
 | 
| 
 | 
   289 
 | 
| 
 | 
   290 		public static Type GetType(Type sourceType)
 | 
| 
 | 
   291 		{
 | 
| 
 | 
   292 			return
 | 
| 
 | 
   293 				TypeHelper.IsScalar(sourceType) || sourceType.IsSealed ||
 | 
| 
 | 
   294 						(!sourceType.IsAbstract && sourceType.IsDefined(typeof(BLToolkitGeneratedAttribute), true)) ?
 | 
| 
 | 
   295 					sourceType:
 | 
| 
 | 
   296 					GetType(sourceType, sourceType, new AbstractClassBuilder(sourceType));
 | 
| 
 | 
   297 		}
 | 
| 
 | 
   298 
 | 
| 
 | 
   299 		static class InstanceCreator<T>
 | 
| 
 | 
   300 		{
 | 
| 
 | 
   301 			public static readonly Func<T> CreateInstance = Expression.Lambda<Func<T>>(Expression.New(TypeFactory.GetType(typeof(T)))).Compile();
 | 
| 
 | 
   302 		}
 | 
| 
 | 
   303 
 | 
| 
 | 
   304 		public static T CreateInstance<T>() where T: class
 | 
| 
 | 
   305 		{
 | 
| 
 | 
   306 			return InstanceCreator<T>.CreateInstance();
 | 
| 
 | 
   307 		}
 | 
| 
 | 
   308 
 | 
| 
 | 
   309 		#endregion
 | 
| 
 | 
   310 
 | 
| 
 | 
   311 		#region Private Helpers
 | 
| 
 | 
   312 
 | 
| 
 | 
   313 		static Assembly LoadExtensionAssembly(Assembly originalAssembly)
 | 
| 
 | 
   314 		{
 | 
| 
 | 
   315 #if !SILVERLIGHT
 | 
| 
 | 
   316 
 | 
| 
 | 
   317 			if (originalAssembly is _AssemblyBuilder)
 | 
| 
 | 
   318 			{
 | 
| 
 | 
   319 				// This is a generated assembly. Even if it has a valid Location,
 | 
| 
 | 
   320 				// there is definitelly no extension assembly at this path.
 | 
| 
 | 
   321 				//
 | 
| 
 | 
   322 				return null;
 | 
| 
 | 
   323 			}
 | 
| 
 | 
   324 
 | 
| 
 | 
   325 			try
 | 
| 
 | 
   326 			{
 | 
| 
 | 
   327 				var originalAssemblyLocation  = new Uri(originalAssembly.EscapedCodeBase).LocalPath;
 | 
| 
 | 
   328 				var extensionAssemblyLocation = Path.ChangeExtension(
 | 
| 
 | 
   329 					originalAssemblyLocation, "BLToolkitExtension.dll");
 | 
| 
 | 
   330 
 | 
| 
 | 
   331 				if (File.GetLastWriteTime(originalAssemblyLocation) <= File.GetLastWriteTime(extensionAssemblyLocation))
 | 
| 
 | 
   332 					return Assembly.LoadFrom(extensionAssemblyLocation);
 | 
| 
 | 
   333 
 | 
| 
 | 
   334 				Debug.WriteLineIf(File.Exists(extensionAssemblyLocation),
 | 
| 
 | 
   335 					string.Format("Extension assembly '{0}' is out of date. Please rebuild.",
 | 
| 
 | 
   336 						extensionAssemblyLocation), typeof(TypeAccessor).FullName);
 | 
| 
 | 
   337 
 | 
| 
 | 
   338 				// Some good man may load this assembly already. Like IIS does it.
 | 
| 
 | 
   339 				//
 | 
| 
 | 
   340 				var extensionAssemblyName = originalAssembly.GetName(true);
 | 
| 
 | 
   341 				extensionAssemblyName.Name += ".BLToolkitExtension";
 | 
| 
 | 
   342 
 | 
| 
 | 
   343 				foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
 | 
| 
 | 
   344 				{
 | 
| 
 | 
   345 					// Note that assembly version and strong name are compared too.
 | 
| 
 | 
   346 					//
 | 
| 
 | 
   347 					if (AssemblyName.ReferenceMatchesDefinition(assembly.GetName(false), extensionAssemblyName))
 | 
| 
 | 
   348 						return assembly;
 | 
| 
 | 
   349 				}
 | 
| 
 | 
   350 			}
 | 
| 
 | 
   351 			catch (Exception ex)
 | 
| 
 | 
   352 			{
 | 
| 
 | 
   353 				// Extension exist, but can't be loaded for some reason.
 | 
| 
 | 
   354 				// Switch back to code generation
 | 
| 
 | 
   355 				//
 | 
| 
 | 
   356 				Debug.WriteLine(ex, typeof(TypeAccessor).FullName);
 | 
| 
 | 
   357 			}
 | 
| 
 | 
   358 
 | 
| 
 | 
   359 #endif
 | 
| 
 | 
   360 
 | 
| 
 | 
   361 			return null;
 | 
| 
 | 
   362 		}
 | 
| 
 | 
   363 
 | 
| 
 | 
   364 		[Conditional("DEBUG")]
 | 
| 
 | 
   365 		private static void WriteDebug(string format, params object[] parameters)
 | 
| 
 | 
   366 		{
 | 
| 
 | 
   367 			Debug.WriteLine(string.Format(format, parameters));
 | 
| 
 | 
   368 		}
 | 
| 
 | 
   369 
 | 
| 
 | 
   370 		#endregion
 | 
| 
 | 
   371 
 | 
| 
 | 
   372 		#region Resolve Types
 | 
| 
 | 
   373 
 | 
| 
 | 
   374 		/// <summary>
 | 
| 
 | 
   375 		/// Initializes AssemblyResolve hooks for the current <see cref="AppDomain"/>.
 | 
| 
 | 
   376 		/// </summary>
 | 
| 
 | 
   377 		public static void Init()
 | 
| 
 | 
   378 		{
 | 
| 
 | 
   379 			//
 | 
| 
 | 
   380 			// The code actually does nothing except an implicit call to the type constructor.
 | 
| 
 | 
   381 			//
 | 
| 
 | 
   382 		}
 | 
| 
 | 
   383 
 | 
| 
 | 
   384 		public static Assembly AssemblyResolver(object sender, ResolveEventArgs args)
 | 
| 
 | 
   385 		{
 | 
| 
 | 
   386 			var name      = args.Name;
 | 
| 
 | 
   387 			var nameParts = name.Split(',');
 | 
| 
 | 
   388 
 | 
| 
 | 
   389 			if (nameParts.Length > 0 && nameParts[0].ToLower().EndsWith(".dll"))
 | 
| 
 | 
   390 			{
 | 
| 
 | 
   391 				nameParts[0] = nameParts[0].Substring(0, nameParts[0].Length - 4);
 | 
| 
 | 
   392 				name         = string.Join(",", nameParts);
 | 
| 
 | 
   393 			}
 | 
| 
 | 
   394 
 | 
| 
 | 
   395 			lock (_builtTypes)
 | 
| 
 | 
   396 				foreach (var type in _builtTypes.Keys)
 | 
| 
 | 
   397 					if (type.FullName == name)
 | 
| 
 | 
   398 						return type.Assembly;
 | 
| 
 | 
   399 
 | 
| 
 | 
   400 #if !SILVERLIGHT
 | 
| 
 | 
   401 
 | 
| 
 | 
   402 			var idx = name.IndexOf("." + TypeBuilderConsts.AssemblyNameSuffix);
 | 
| 
 | 
   403 
 | 
| 
 | 
   404 			if (idx > 0)
 | 
| 
 | 
   405 			{
 | 
| 
 | 
   406 				var typeName = name.Substring(0, idx);
 | 
| 
 | 
   407 				var type     = Type.GetType(typeName);
 | 
| 
 | 
   408 
 | 
| 
 | 
   409 				if (type == null)
 | 
| 
 | 
   410 				{
 | 
| 
 | 
   411 					var ass = ((AppDomain)sender).GetAssemblies();
 | 
| 
 | 
   412 
 | 
| 
 | 
   413 					// CLR can't find an assembly built on previous AssemblyResolve event.
 | 
| 
 | 
   414 					//
 | 
| 
 | 
   415 					for (var i = ass.Length - 1; i >= 0; i--)
 | 
| 
 | 
   416 					{
 | 
| 
 | 
   417 						if (string.Compare(ass[i].FullName, name) == 0)
 | 
| 
 | 
   418 							return ass[i];
 | 
| 
 | 
   419 					}
 | 
| 
 | 
   420 
 | 
| 
 | 
   421 					for (var i = ass.Length - 1; i >= 0; i--)
 | 
| 
 | 
   422 					{
 | 
| 
 | 
   423 						var a = ass[i];
 | 
| 
 | 
   424 
 | 
| 
 | 
   425 						if (!(
 | 
| 
 | 
   426 #if FW4
 | 
| 
 | 
   427 							a.IsDynamic ||
 | 
| 
 | 
   428 #endif
 | 
| 
 | 
   429 							a is _AssemblyBuilder) &&
 | 
| 
 | 
   430 							(a.CodeBase.IndexOf("Microsoft.NET/Framework") > 0 || a.FullName.StartsWith("System."))) continue;
 | 
| 
 | 
   431 
 | 
| 
 | 
   432 						type = a.GetType(typeName);
 | 
| 
 | 
   433 
 | 
| 
 | 
   434 						if (type != null) break;
 | 
| 
 | 
   435 
 | 
| 
 | 
   436 						foreach (var t in a.GetTypes())
 | 
| 
 | 
   437 						{
 | 
| 
 | 
   438 							if (!t.IsAbstract)
 | 
| 
 | 
   439 								continue;
 | 
| 
 | 
   440 
 | 
| 
 | 
   441 							if (t.FullName == typeName)
 | 
| 
 | 
   442 							{
 | 
| 
 | 
   443 								type = t;
 | 
| 
 | 
   444 							}
 | 
| 
 | 
   445 							else
 | 
| 
 | 
   446 							{
 | 
| 
 | 
   447 								if (t.FullName.IndexOf('+') > 0)
 | 
| 
 | 
   448 								{
 | 
| 
 | 
   449 									var s = typeName;
 | 
| 
 | 
   450 
 | 
| 
 | 
   451 									while (type == null && (idx = s.LastIndexOf(".")) > 0)
 | 
| 
 | 
   452 									{
 | 
| 
 | 
   453 										s = s.Remove(idx, 1).Insert(idx, "+");
 | 
| 
 | 
   454 
 | 
| 
 | 
   455 										if (t.FullName == s)
 | 
| 
 | 
   456 											type = t;
 | 
| 
 | 
   457 									}
 | 
| 
 | 
   458 								}
 | 
| 
 | 
   459 							}
 | 
| 
 | 
   460 
 | 
| 
 | 
   461 							if (type != null) break;
 | 
| 
 | 
   462 						}
 | 
| 
 | 
   463 
 | 
| 
 | 
   464 						if (type != null) break;
 | 
| 
 | 
   465 					}
 | 
| 
 | 
   466 				}
 | 
| 
 | 
   467 
 | 
| 
 | 
   468 				if (type != null)
 | 
| 
 | 
   469 				{
 | 
| 
 | 
   470 					var newType = GetType(type);
 | 
| 
 | 
   471 
 | 
| 
 | 
   472 					if (newType.Assembly.FullName == name)
 | 
| 
 | 
   473 						return newType.Assembly;
 | 
| 
 | 
   474 				}
 | 
| 
 | 
   475 			}
 | 
| 
 | 
   476 
 | 
| 
 | 
   477 #endif
 | 
| 
 | 
   478 
 | 
| 
 | 
   479 			return null;
 | 
| 
 | 
   480 		}
 | 
| 
 | 
   481 
 | 
| 
 | 
   482 		#endregion
 | 
| 
 | 
   483 	}
 | 
| 
 | 
   484 }
 |