Ejemplo n.º 1
0
		/// <summary>
		/// Determines whether this assembly has internals visible to dynamic proxy.
		/// </summary>
		/// <param name="asm">The assembly to inspect.</param>
		public static bool IsInternalToDynamicProxy(Assembly asm)
		{
			using (UpgradableLock locker = new UpgradableLock(internalsToDynProxyLock))
			{
				if (internalsToDynProxy.ContainsKey(asm))
				{
					return internalsToDynProxy[asm];
				}

				locker.Upgrade();

				if (internalsToDynProxy.ContainsKey(asm))
				{
					return internalsToDynProxy[asm];
				}

				InternalsVisibleToAttribute[] atts = (InternalsVisibleToAttribute[])
				                                     asm.GetCustomAttributes(typeof (InternalsVisibleToAttribute), false);

				bool found = false;

				foreach (InternalsVisibleToAttribute internals in atts)
				{
					if (internals.AssemblyName.Contains(ModuleScope.DEFAULT_ASSEMBLY_NAME))
					{
						found = true;
						break;
					}
				}

				internalsToDynProxy.Add(asm, found);

				return found;
			}
		}
		public Type GenerateCode(Type proxyTargetType, Type[] interfaces, ProxyGenerationOptions options)
		{
			// make sure ProxyGenerationOptions is initialized
			options.Initialize();

			CheckNotGenericTypeDefinition(proxyTargetType, "proxyTargetType");
			CheckNotGenericTypeDefinitions(interfaces, "interfaces");
			Type generatedType;

			CacheKey cacheKey = new CacheKey(proxyTargetType, targetType, interfaces, options);

			using (UpgradableLock locker = new UpgradableLock(Scope.RWLock))
			{
				Type cacheType = GetFromCache(cacheKey);

				if (cacheType != null)
				{
					return cacheType;
				}

				locker.Upgrade();

				cacheType = GetFromCache(cacheKey);

				if (cacheType != null)
				{
					return cacheType;
				}

				SetGenerationOptions(options);

				String newName = targetType.Name + "Proxy" + Guid.NewGuid().ToString("N");

				// Add Interfaces that the proxy implements 

				List<Type> interfaceList = new List<Type>();

				interfaceList.Add(targetType);

				if (interfaces != null)
				{
					interfaceList.AddRange(interfaces);
				}
#if SILVERLIGHT
#warning What to do?
#else
				if (!interfaceList.Contains(typeof(ISerializable)))
					interfaceList.Add(typeof(ISerializable));
#endif

				AddMixinInterfaces(interfaceList);
				AddDefaultInterfaces(interfaceList);

				Type baseType = options.BaseTypeForInterfaceProxy;

				ClassEmitter emitter = BuildClassEmitter(newName, baseType, interfaceList);
				CreateOptionsField(emitter);
                emitter.AddCustomAttributes(options);
#if SILVERLIGHT
#warning XmlIncludeAttribute is in silverlight, do we want to explore this?
#else
				emitter.DefineCustomAttribute(new XmlIncludeAttribute(targetType));
				emitter.DefineCustomAttribute(new SerializableAttribute());
#endif

				// Custom attributes
				ReplicateNonInheritableAttributes(targetType, emitter);

				// Fields generations

				FieldReference interceptorsField = emitter.CreateField("__interceptors", typeof(IInterceptor[]));
				targetField = emitter.CreateField("__target", proxyTargetType);

#if SILVERLIGHT
#warning XmlIncludeAttribute is in silverlight, do we want to explore this?
#else
				emitter.DefineCustomAttributeFor(interceptorsField, new XmlIgnoreAttribute());
				emitter.DefineCustomAttributeFor(targetField, new XmlIgnoreAttribute());
#endif
				// Implement builtin Interfaces
				ImplementProxyTargetAccessor(targetType, emitter, interceptorsField);

				// Collect methods

				PropertyToGenerate[] propsToGenerate;
				EventToGenerate[] eventToGenerates;
				MethodInfo[] methods = CollectMethodsAndProperties(emitter, targetType, out propsToGenerate, out eventToGenerates);

				if (interfaces != null && interfaces.Length != 0)
				{
					List<Type> tmpInterfaces = new List<Type>(interfaces);

					foreach (Type inter in interfaces)
					{
						if (inter.IsAssignableFrom(proxyTargetType))
						{
							PropertyToGenerate[] tempPropsToGenerate;
							EventToGenerate[] tempEventToGenerates;
							MethodInfo[] methodsTemp =
								CollectMethodsAndProperties(emitter, inter, out tempPropsToGenerate, out tempEventToGenerates);

							PropertyToGenerate[] newPropsToGenerate =
								new PropertyToGenerate[tempPropsToGenerate.Length + propsToGenerate.Length];
							MethodInfo[] newMethods = new MethodInfo[methodsTemp.Length + methods.Length];
							EventToGenerate[] newEvents = new EventToGenerate[eventToGenerates.Length + tempEventToGenerates.Length];

							Array.Copy(methods, newMethods, methods.Length);
							Array.Copy(methodsTemp, 0, newMethods, methods.Length, methodsTemp.Length);

							Array.Copy(propsToGenerate, newPropsToGenerate, propsToGenerate.Length);
							Array.Copy(tempPropsToGenerate, 0, newPropsToGenerate, propsToGenerate.Length, tempPropsToGenerate.Length);

							Array.Copy(eventToGenerates, newEvents, eventToGenerates.Length);
							Array.Copy(tempEventToGenerates, 0, newEvents, eventToGenerates.Length, tempEventToGenerates.Length);

							methods = newMethods;
							propsToGenerate = newPropsToGenerate;
							eventToGenerates = newEvents;

							tmpInterfaces.Remove(inter);
						}
					}

					interfaces = tmpInterfaces.ToArray();
				}

				RegisterMixinMethodsAndProperties(emitter, ref methods, ref propsToGenerate, ref eventToGenerates);

				options.Hook.MethodsInspected();

				// Constructor

				ConstructorEmitter typeInitializer = GenerateStaticConstructor(emitter);

				if (!proxyTargetType.IsInterface)
				{
					CacheMethodTokens(emitter, MethodFinder.GetAllInstanceMethods(proxyTargetType,
																				  BindingFlags.Public | BindingFlags.Instance),
									  typeInitializer);
				}

				CreateInitializeCacheMethodBody(proxyTargetType, methods, emitter, typeInitializer);
				FieldReference[] mixinFields = AddMixinFields(emitter);
				List<FieldReference> fields = new List<FieldReference>(mixinFields);
				fields.Add(interceptorsField);
				fields.Add(targetField);
				GenerateConstructors(emitter, baseType, fields.ToArray());
				// GenerateParameterlessConstructor(emitter, interceptorsField, baseType);

				// Implement interfaces

				if (interfaces != null && interfaces.Length != 0)
				{
					foreach (Type inter in interfaces)
					{
						ImplementBlankInterface(targetType, inter, emitter, interceptorsField, typeInitializer, AllowChangeTarget);
					}
				}

				// Create invocation types

				foreach (MethodInfo method in methods)
				{
					CreateInvocationForMethod(emitter, method, proxyTargetType);
				}

				// Create methods overrides

				Dictionary<MethodInfo, MethodEmitter> method2Emitter = new Dictionary<MethodInfo, MethodEmitter>();

				foreach (MethodInfo method in methods)
				{
					if (method.IsSpecialName &&
						(method.Name.StartsWith("get_") || method.Name.StartsWith("set_") ||
						 method.Name.StartsWith("add_") || method.Name.StartsWith("remove_")) ||
						methodsToSkip.Contains(method))
					{
						continue;
					}

					NestedClassEmitter nestedClass = (NestedClassEmitter)method2Invocation[method];

					MethodEmitter newProxiedMethod = CreateProxiedMethod(
						targetType, method, emitter, nestedClass, interceptorsField, GetTargetRef(method, mixinFields, targetField),
						ConstructorVersion.WithTargetMethod, (MethodInfo)method2methodOnTarget[method]);

					ReplicateNonInheritableAttributes(method, newProxiedMethod);

					method2Emitter[method] = newProxiedMethod;
				}

				foreach (PropertyToGenerate propToGen in propsToGenerate)
				{
					if (propToGen.CanRead)
					{
						NestedClassEmitter nestedClass = (NestedClassEmitter)method2Invocation[propToGen.GetMethod];

						MethodAttributes atts = ObtainMethodAttributes(propToGen.GetMethod);

						MethodEmitter getEmitter = propToGen.Emitter.CreateGetMethod(atts);

						ImplementProxiedMethod(targetType, getEmitter,
											   propToGen.GetMethod, emitter,
											   nestedClass, interceptorsField, GetTargetRef(propToGen.GetMethod, mixinFields, targetField),
											   ConstructorVersion.WithTargetMethod,
											   (MethodInfo)method2methodOnTarget[propToGen.GetMethod]);

						ReplicateNonInheritableAttributes(propToGen.GetMethod, getEmitter);

						// emitter.TypeBuilder.DefineMethodOverride(getEmitter.MethodBuilder, propToGen.GetMethod);
					}

					if (propToGen.CanWrite)
					{
						NestedClassEmitter nestedClass = (NestedClassEmitter)method2Invocation[propToGen.SetMethod];

						MethodAttributes atts = ObtainMethodAttributes(propToGen.SetMethod);

						MethodEmitter setEmitter = propToGen.Emitter.CreateSetMethod(atts);

						ImplementProxiedMethod(targetType, setEmitter,
											   propToGen.SetMethod, emitter,
											   nestedClass, interceptorsField, GetTargetRef(propToGen.SetMethod, mixinFields, targetField),
											   ConstructorVersion.WithTargetMethod,
											   (MethodInfo)method2methodOnTarget[propToGen.SetMethod]);

						ReplicateNonInheritableAttributes(propToGen.SetMethod, setEmitter);

						// emitter.TypeBuilder.DefineMethodOverride(setEmitter.MethodBuilder, propToGen.SetMethod);
					}
				}


				foreach (EventToGenerate eventToGenerate in eventToGenerates)
				{
					NestedClassEmitter add_nestedClass = (NestedClassEmitter)method2Invocation[eventToGenerate.AddMethod];

					MethodAttributes add_atts = ObtainMethodAttributes(eventToGenerate.AddMethod);

					MethodEmitter addEmitter = eventToGenerate.Emitter.CreateAddMethod(add_atts);

					ImplementProxiedMethod(targetType, addEmitter,
										   eventToGenerate.AddMethod, emitter,
										   add_nestedClass, interceptorsField,
										   GetTargetRef(eventToGenerate.AddMethod, mixinFields, targetField),
										   ConstructorVersion.WithTargetMethod,
										   (MethodInfo)method2methodOnTarget[eventToGenerate.AddMethod]);

					ReplicateNonInheritableAttributes(eventToGenerate.AddMethod, addEmitter);


					NestedClassEmitter remove_nestedClass = (NestedClassEmitter)method2Invocation[eventToGenerate.RemoveMethod];

					MethodAttributes remove_atts = ObtainMethodAttributes(eventToGenerate.RemoveMethod);

					MethodEmitter removeEmitter = eventToGenerate.Emitter.CreateRemoveMethod(remove_atts);

					ImplementProxiedMethod(targetType, removeEmitter,
										   eventToGenerate.RemoveMethod, emitter,
										   remove_nestedClass, interceptorsField,
										   GetTargetRef(eventToGenerate.RemoveMethod, mixinFields, targetField),
										   ConstructorVersion.WithTargetMethod,
										   (MethodInfo)method2methodOnTarget[eventToGenerate.RemoveMethod]);

					ReplicateNonInheritableAttributes(eventToGenerate.RemoveMethod, removeEmitter);
				}

#if SILVERLIGHT
#warning What to do?
#else
				ImplementGetObjectData(emitter, interceptorsField, mixinFields, interfaces);
#endif

				// Complete Initialize 

				CompleteInitCacheMethod(typeInitializer.CodeBuilder);

				// Crosses fingers and build type

				generatedType = emitter.BuildType();
				InitializeStaticFields(generatedType);

				/*foreach (MethodInfo m in TypeFinder.GetMethods(generatedType, BindingFlags.Instance | BindingFlags.Public))
				{
					ParameterInfo[] parameters = m.GetParameters();

					// Console.WriteLine(m.Name);

					for (int i = 0; i < parameters.Length; i++)
					{
						ParameterInfo paramInfo = parameters[i];

						// Console.WriteLine("{0} {1} {2} {3}", paramInfo.Name, paramInfo.ParameterType, paramInfo.Attributes, paramInfo.Position);
						// Console.WriteLine("{0} {1} {2} {3}", paramInfo2.Name, paramInfo2.ParameterType, paramInfo2.Attributes, paramInfo2.Position);
					}
				}
				*/

				AddToCache(cacheKey, generatedType);
			}

			return generatedType;
		}
Ejemplo n.º 3
0
		public Type GenerateCode(Type[] interfaces, ProxyGenerationOptions options)
		{
			// make sure ProxyGenerationOptions is initialized
			options.Initialize();

			CheckNotGenericTypeDefinitions(interfaces, "interfaces");
			Type type;

			CacheKey cacheKey = new CacheKey(targetType, interfaces, options);

			using (UpgradableLock locker = new UpgradableLock(Scope.RWLock))
			{
				Type cacheType = GetFromCache(cacheKey);

				if (cacheType != null)
				{
					return cacheType;
				}

				locker.Upgrade();

				cacheType = GetFromCache(cacheKey);

				if (cacheType != null)
				{
					return cacheType;
				}

				SetGenerationOptions(options);

				String newName = targetType.Name + "Proxy" + Guid.NewGuid().ToString("N");

				// Add Interfaces that the proxy implements 

				List<Type> interfaceList = new List<Type>();

				if (interfaces != null)
				{
					interfaceList.AddRange(interfaces);
				}

				AddMixinInterfaces(interfaceList);

				AddDefaultInterfaces(interfaceList);

#if !SILVERLIGHT
				if (targetType.IsSerializable)
				{
					delegateToBaseGetObjectData = VerifyIfBaseImplementsGetObjectData(targetType);

					if (!interfaceList.Contains(typeof(ISerializable)))
					{
						interfaceList.Add(typeof(ISerializable));
					}
				}
#endif
				ClassEmitter emitter = BuildClassEmitter(newName, targetType, interfaceList);
				CreateOptionsField(emitter);
                emitter.AddCustomAttributes(options);

#if !SILVERLIGHT
				emitter.DefineCustomAttribute(new XmlIncludeAttribute(targetType));
#endif
				// Custom attributes

				ReplicateNonInheritableAttributes(targetType, emitter);

				// Fields generations

				FieldReference interceptorsField =
					emitter.CreateField("__interceptors", typeof (IInterceptor[]));

				// Implement builtin Interfaces
				ImplementProxyTargetAccessor(targetType, emitter, interceptorsField);

#if !SILVERLIGHT
				emitter.DefineCustomAttributeFor(interceptorsField, new XmlIgnoreAttribute());
#endif
				// Collect methods

				PropertyToGenerate[] propsToGenerate;
				EventToGenerate[] eventToGenerates;
				MethodInfo[] methods = CollectMethodsAndProperties(emitter, targetType, out propsToGenerate, out eventToGenerates);

				RegisterMixinMethodsAndProperties(emitter, ref methods, ref propsToGenerate, ref eventToGenerates);

				options.Hook.MethodsInspected();

				// Constructor

				ConstructorEmitter typeInitializer = GenerateStaticConstructor(emitter);

				FieldReference[] mixinFields = AddMixinFields(emitter);

				// constructor arguments
				List<FieldReference> constructorArguments = new List<FieldReference>(mixinFields);
				constructorArguments.Add(interceptorsField);

				CreateInitializeCacheMethodBody(targetType, methods, emitter, typeInitializer);
				GenerateConstructors(emitter, targetType, constructorArguments.ToArray());
				GenerateParameterlessConstructor(emitter, targetType, interceptorsField);

#if !SILVERLIGHT
				if (delegateToBaseGetObjectData)
				{
					GenerateSerializationConstructor(emitter, interceptorsField, mixinFields);
				}
#endif
				// Implement interfaces

				if (interfaces != null && interfaces.Length != 0)
				{
					foreach (Type inter in interfaces)
					{
						ImplementBlankInterface(targetType, inter, emitter, interceptorsField, typeInitializer);
					}
				}

				// Create callback methods

				Dictionary<MethodInfo, MethodBuilder> method2Callback = new Dictionary<MethodInfo, MethodBuilder>();

				foreach (MethodInfo method in methods)
				{
					method2Callback[method] = CreateCallbackMethod(emitter, method, method);
				}

				// Create invocation types

				Dictionary<MethodInfo, NestedClassEmitter> method2Invocation = new Dictionary<MethodInfo, NestedClassEmitter>();

				foreach (MethodInfo method in methods)
				{
					MethodBuilder callbackMethod = method2Callback[method];

					method2Invocation[method] = BuildInvocationNestedType(emitter, targetType,
					                                                      IsMixinMethod(method)
					                                                      	? method.DeclaringType
					                                                      	: emitter.TypeBuilder,
					                                                      method, callbackMethod,
					                                                      ConstructorVersion.WithoutTargetMethod);
				}

				// Create methods overrides

				Dictionary<MethodInfo, MethodEmitter> method2Emitter = new Dictionary<MethodInfo, MethodEmitter>();

				foreach (MethodInfo method in methods)
				{
					if (method.IsSpecialName &&
					    (method.Name.StartsWith("get_") || method.Name.StartsWith("set_") ||
					     method.Name.StartsWith("add_") || method.Name.StartsWith("remove_")) ||
					    methodsToSkip.Contains(method))
					{
						continue;
					}

					NestedClassEmitter nestedClass = method2Invocation[method];

					Reference targetRef = GetTargetRef(method, mixinFields, SelfReference.Self);
					MethodEmitter newProxiedMethod = CreateProxiedMethod(
						targetType, method, emitter, nestedClass, interceptorsField, targetRef,
						ConstructorVersion.WithoutTargetMethod, null);

					ReplicateNonInheritableAttributes(method, newProxiedMethod);

					method2Emitter[method] = newProxiedMethod;
				}

				foreach (PropertyToGenerate propToGen in propsToGenerate)
				{
					if (propToGen.CanRead)
					{
						NestedClassEmitter nestedClass = method2Invocation[propToGen.GetMethod];

						MethodAttributes atts = ObtainMethodAttributes(propToGen.GetMethod);

						MethodEmitter getEmitter = propToGen.Emitter.CreateGetMethod(atts);

						Reference targetRef = GetTargetRef(propToGen.GetMethod, mixinFields, SelfReference.Self);

						ImplementProxiedMethod(targetType, getEmitter,
						                       propToGen.GetMethod, emitter,
						                       nestedClass, interceptorsField, targetRef,
						                       ConstructorVersion.WithoutTargetMethod, null);

						ReplicateNonInheritableAttributes(propToGen.GetMethod, getEmitter);
					}

					if (propToGen.CanWrite)
					{
						NestedClassEmitter nestedClass = method2Invocation[propToGen.SetMethod];

						MethodAttributes atts = ObtainMethodAttributes(propToGen.SetMethod);

						MethodEmitter setEmitter = propToGen.Emitter.CreateSetMethod(atts);

						Reference targetRef = GetTargetRef(propToGen.SetMethod, mixinFields, SelfReference.Self);

						ImplementProxiedMethod(targetType, setEmitter,
						                       propToGen.SetMethod, emitter,
						                       nestedClass, interceptorsField, targetRef,
						                       ConstructorVersion.WithoutTargetMethod, null);

						ReplicateNonInheritableAttributes(propToGen.SetMethod, setEmitter);
					}
				}

				foreach (EventToGenerate eventToGenerate in eventToGenerates)
				{
					NestedClassEmitter add_nestedClass = method2Invocation[eventToGenerate.AddMethod];

					MethodAttributes add_atts = ObtainMethodAttributes(eventToGenerate.AddMethod);

					MethodEmitter addEmitter = eventToGenerate.Emitter.CreateAddMethod(add_atts);

					ImplementProxiedMethod(targetType, addEmitter,
					                       eventToGenerate.AddMethod, emitter,
					                       add_nestedClass, interceptorsField,
					                       GetTargetRef(eventToGenerate.AddMethod, mixinFields, SelfReference.Self),
					                       ConstructorVersion.WithoutTargetMethod, null);

					ReplicateNonInheritableAttributes(eventToGenerate.AddMethod, addEmitter);

					NestedClassEmitter remove_nestedClass = method2Invocation[eventToGenerate.RemoveMethod];

					MethodAttributes remove_atts = ObtainMethodAttributes(eventToGenerate.RemoveMethod);

					MethodEmitter removeEmitter = eventToGenerate.Emitter.CreateRemoveMethod(remove_atts);

					ImplementProxiedMethod(targetType, removeEmitter,
					                       eventToGenerate.RemoveMethod, emitter,
					                       remove_nestedClass, interceptorsField,
					                       GetTargetRef(eventToGenerate.RemoveMethod, mixinFields, SelfReference.Self),
					                       ConstructorVersion.WithoutTargetMethod, null);

					ReplicateNonInheritableAttributes(eventToGenerate.RemoveMethod, removeEmitter);
				}

#if !SILVERLIGHT
				ImplementGetObjectData(emitter, interceptorsField, mixinFields, interfaces);
#endif

				// Complete type initializer code body

				CompleteInitCacheMethod(typeInitializer.CodeBuilder);

				// Build type

				type = emitter.BuildType();
				InitializeStaticFields(type);

				AddToCache(cacheKey, type);
			}

			return type;
		}