diff Source/Reflection/Emit/TypeBuilderHelper.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/Reflection/Emit/TypeBuilderHelper.cs	Thu Mar 27 21:46:09 2014 +0400
@@ -0,0 +1,578 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Reflection.Emit;
+
+namespace BLToolkit.Reflection.Emit
+{
+	using TypeBuilder.Builders;
+
+	/// <summary>
+	/// A wrapper around the <see cref="TypeBuilder"/> class.
+	/// </summary>
+	/// <include file="Examples.CS.xml" path='examples/emit[@name="Emit"]/*' />
+	/// <include file="Examples.VB.xml" path='examples/emit[@name="Emit"]/*' />
+	/// <seealso cref="System.Reflection.Emit.TypeBuilder">TypeBuilder Class</seealso>
+	public class TypeBuilderHelper
+	{
+		/// <summary>
+		/// Initializes a new instance of the <see cref="TypeBuilderHelper"/> class
+		/// with the specified parameters.
+		/// </summary>
+		/// <param name="assemblyBuilder">Associated <see cref="AssemblyBuilderHelper"/>.</param>
+		/// <param name="typeBuilder">A <see cref="TypeBuilder"/></param>
+		public TypeBuilderHelper(AssemblyBuilderHelper assemblyBuilder, System.Reflection.Emit.TypeBuilder typeBuilder)
+		{
+			if (assemblyBuilder == null) throw new ArgumentNullException("assemblyBuilder");
+			if (typeBuilder     == null) throw new ArgumentNullException("typeBuilder");
+
+			_assembly    = assemblyBuilder;
+			_typeBuilder = typeBuilder;
+
+			_typeBuilder.SetCustomAttribute(_assembly.BLToolkitAttribute);
+		}
+
+		private readonly AssemblyBuilderHelper _assembly;
+		/// <summary>
+		/// Gets associated <see cref="AssemblyBuilderHelper"/>.
+		/// </summary>
+		public  AssemblyBuilderHelper  Assembly
+		{
+			get { return _assembly; }
+		}
+
+		private readonly System.Reflection.Emit.TypeBuilder _typeBuilder;
+		/// <summary>
+		/// Gets <see cref="System.Reflection.Emit.TypeBuilder"/>.
+		/// </summary>
+		public  System.Reflection.Emit.TypeBuilder  TypeBuilder
+		{
+			get { return _typeBuilder; }
+		}
+
+		/// <summary>
+		/// Converts the supplied <see cref="TypeBuilderHelper"/> to a <see cref="TypeBuilder"/>.
+		/// </summary>
+		/// <param name="typeBuilder">The <see cref="TypeBuilderHelper"/>.</param>
+		/// <returns>A <see cref="TypeBuilder"/>.</returns>
+		public static implicit operator System.Reflection.Emit.TypeBuilder(TypeBuilderHelper typeBuilder)
+		{
+			if (typeBuilder == null) throw new ArgumentNullException("typeBuilder");
+
+			return typeBuilder.TypeBuilder;
+		}
+
+		#region DefineMethod Overrides
+
+		/// <summary>
+		/// Adds a new method to the class, with the given name and method signature.
+		/// </summary>
+		/// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
+		/// <param name="attributes">The attributes of the method. </param>
+		/// <param name="returnType">The return type of the method.</param>
+		/// <param name="parameterTypes">The types of the parameters of the method.</param>
+		/// <returns>The defined method.</returns>
+		public MethodBuilderHelper DefineMethod(
+			string name, MethodAttributes attributes, Type returnType, params Type[] parameterTypes)
+		{
+			return new MethodBuilderHelper(this, _typeBuilder.DefineMethod(name, attributes, returnType, parameterTypes));
+		}
+
+		/// <summary>
+		/// Adds a new method to the class, with the given name and method signature.
+		/// </summary>
+		/// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
+		/// <param name="attributes">The attributes of the method. </param>
+		/// <param name="callingConvention">The <see cref="CallingConventions">calling convention</see> of the method.</param>
+		/// <param name="returnType">The return type of the method.</param>
+		/// <param name="parameterTypes">The types of the parameters of the method.</param>
+		/// <returns>The defined method.</returns>
+		public MethodBuilderHelper DefineMethod(
+			string             name,
+			MethodAttributes   attributes,
+			CallingConventions callingConvention,
+			Type               returnType,
+			Type[]             parameterTypes)
+		{
+			return new MethodBuilderHelper(this, _typeBuilder.DefineMethod(
+				name, attributes, callingConvention, returnType, parameterTypes));
+		}
+
+		/// <summary>
+		/// Adds a new method to the class, with the given name and method signature.
+		/// </summary>
+		/// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
+		/// <param name="attributes">The attributes of the method. </param>
+		/// <param name="returnType">The return type of the method.</param>
+		/// <returns>The defined method.</returns>
+		public MethodBuilderHelper DefineMethod(string name, MethodAttributes attributes, Type returnType)
+		{
+			return new MethodBuilderHelper(
+				this,
+				_typeBuilder.DefineMethod(name, attributes, returnType, Type.EmptyTypes));
+		}
+
+		/// <summary>
+		/// Adds a new method to the class, with the given name and method signature.
+		/// </summary>
+		/// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
+		/// <param name="attributes">The attributes of the method. </param>
+		/// <returns>The defined method.</returns>
+		public MethodBuilderHelper DefineMethod(string name, MethodAttributes attributes)
+		{
+			return new MethodBuilderHelper(
+				this,
+				_typeBuilder.DefineMethod(name, attributes, typeof(void), Type.EmptyTypes));
+		}
+
+		/// <summary>
+		/// Adds a new method to the class, with the given name and method signature.
+		/// </summary>
+		/// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
+		/// <param name="attributes">The attributes of the method. </param>
+		/// <returns>The defined method.</returns>
+		/// <param name="callingConvention">The calling convention of the method.</param>
+		public MethodBuilderHelper DefineMethod(
+			string             name,
+			MethodAttributes   attributes,
+			CallingConventions callingConvention)
+		{
+			return new MethodBuilderHelper(
+				this,
+				_typeBuilder.DefineMethod(name, attributes, callingConvention));
+		}
+
+		/// <summary>
+		/// Adds a new method to the class, with the given name and method signature.
+		/// </summary>
+		/// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
+		/// <param name="attributes">The attributes of the method. </param>
+		/// <param name="callingConvention">The <see cref="CallingConventions">calling convention</see> of the method.</param>
+		/// <param name="genericArguments">Generic arguments of the method.</param>
+		/// <param name="returnType">The return type of the method.</param>
+		/// <param name="parameterTypes">The types of the parameters of the method.</param>
+		/// <returns>The defined generic method.</returns>
+		public MethodBuilderHelper DefineGenericMethod(
+			string             name,
+			MethodAttributes   attributes,
+			CallingConventions callingConvention,
+			Type[]             genericArguments,
+			Type               returnType,
+			Type[]             parameterTypes)
+		{
+			return new MethodBuilderHelper(
+				this,
+				_typeBuilder.DefineMethod(name, attributes, callingConvention), genericArguments, returnType, parameterTypes);
+		}
+
+
+		private Dictionary<MethodInfo, MethodBuilder> _overriddenMethods;
+
+		/// <summary>
+		/// Retrieves the map of base type methods overridden by this type.
+		/// </summary>
+		public  Dictionary<MethodInfo, MethodBuilder>  OverriddenMethods
+		{
+			get { return _overriddenMethods ?? (_overriddenMethods = new Dictionary<MethodInfo,MethodBuilder>()); }
+		}
+
+		/// <summary>
+		/// Adds a new method to the class, with the given name and method signature.
+		/// </summary>
+		/// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
+		/// <param name="methodInfoDeclaration">The method whose declaration is to be used.</param>
+		/// <param name="attributes">The attributes of the method. </param>
+		/// <returns>The defined method.</returns>
+		public MethodBuilderHelper DefineMethod(
+			string           name,
+			MethodInfo       methodInfoDeclaration,
+			MethodAttributes attributes)
+		{
+			if (methodInfoDeclaration == null) throw new ArgumentNullException("methodInfoDeclaration");
+
+			MethodBuilderHelper method;
+			ParameterInfo[]     pi         = methodInfoDeclaration.GetParameters();
+			Type[]              parameters = new Type[pi.Length];
+
+			for (int i = 0; i < pi.Length; i++)
+				parameters[i] = pi[i].ParameterType;
+
+			if (methodInfoDeclaration.ContainsGenericParameters)
+			{
+				method = DefineGenericMethod(
+					name,
+					attributes,
+					methodInfoDeclaration.CallingConvention,
+					methodInfoDeclaration.GetGenericArguments(),
+					methodInfoDeclaration.ReturnType,
+					parameters);
+			}
+			else
+			{
+				method = DefineMethod(
+					name,
+					attributes,
+					methodInfoDeclaration.CallingConvention,
+					methodInfoDeclaration.ReturnType,
+					parameters);
+			}
+
+			// Compiler overrides methods only for interfaces. We do the same.
+			// If we wanted to override virtual methods, then methods should've had
+			// MethodAttributes.VtableLayoutMask attribute
+			// and the following condition should've been used below:
+			// if ((methodInfoDeclaration is FakeMethodInfo) == false)
+			//
+			if (methodInfoDeclaration.DeclaringType.IsInterface
+#if !SILVERLIGHT
+				&& !(methodInfoDeclaration is FakeMethodInfo)
+#endif
+				)
+			{
+				OverriddenMethods.Add(methodInfoDeclaration, method.MethodBuilder);
+				_typeBuilder.DefineMethodOverride(method.MethodBuilder, methodInfoDeclaration);
+			}
+
+			method.OverriddenMethod = methodInfoDeclaration;
+
+			for (int i = 0; i < pi.Length; i++)
+				method.MethodBuilder.DefineParameter(i + 1, pi[i].Attributes, pi[i].Name);
+
+			return method;
+		}
+
+		/// <summary>
+		/// Adds a new method to the class, with the given name and method signature.
+		/// </summary>
+		/// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
+		/// <param name="methodInfoDeclaration">The method whose declaration is to be used.</param>
+		/// <returns>The defined method.</returns>
+		public MethodBuilderHelper DefineMethod(string name, MethodInfo methodInfoDeclaration)
+		{
+			return DefineMethod(name, methodInfoDeclaration, MethodAttributes.Virtual);
+		}
+
+		/// <summary>
+		/// Adds a new private method to the class.
+		/// </summary>
+		/// <param name="methodInfoDeclaration">The method whose declaration is to be used.</param>
+		/// <returns>The defined method.</returns>
+		public MethodBuilderHelper DefineMethod(MethodInfo methodInfoDeclaration)
+		{
+			if (methodInfoDeclaration == null) throw new ArgumentNullException("methodInfoDeclaration");
+
+			var isInterface = methodInfoDeclaration.DeclaringType.IsInterface;
+#if SILVERLIGHT
+			var isFake      = false;
+#else
+			var isFake      = methodInfoDeclaration is FakeMethodInfo;
+#endif
+
+			var name = isInterface && !isFake?
+				methodInfoDeclaration.DeclaringType.FullName + "." + methodInfoDeclaration.Name:
+				methodInfoDeclaration.Name;
+
+			var attributes = 
+				MethodAttributes.Virtual |
+				MethodAttributes.HideBySig |
+				MethodAttributes.PrivateScope |
+				methodInfoDeclaration.Attributes & MethodAttributes.SpecialName;
+
+			if (isInterface && !isFake)
+				attributes |= MethodAttributes.Private;
+			else if ((attributes & MethodAttributes.SpecialName) != 0)
+				attributes |= MethodAttributes.Public;
+			else
+				attributes |= methodInfoDeclaration.Attributes & 
+					(MethodAttributes.Public | MethodAttributes.Private);
+
+			return DefineMethod(name, methodInfoDeclaration, attributes);
+		}
+
+		#endregion
+
+		/// <summary>
+		/// Creates a Type object for the class.
+		/// </summary>
+		/// <returns>Returns the new Type object for this class.</returns>
+		public Type Create()
+		{
+			return TypeBuilder.CreateType();
+		}
+
+		/// <summary>
+		/// Sets a custom attribute using a custom attribute type.
+		/// </summary>
+		/// <param name="attributeType">Attribute type.</param>
+		public void SetCustomAttribute(Type attributeType)
+		{
+			if (attributeType == null) throw new ArgumentNullException("attributeType");
+
+			ConstructorInfo        ci        = attributeType.GetConstructor(Type.EmptyTypes);
+			CustomAttributeBuilder caBuilder = new CustomAttributeBuilder(ci, new object[0]);
+
+			_typeBuilder.SetCustomAttribute(caBuilder);
+		}
+
+		/// <summary>
+		/// Sets a custom attribute using a custom attribute type
+		/// and named properties.
+		/// </summary>
+		/// <param name="attributeType">Attribute type.</param>
+		/// <param name="properties">Named properties of the custom attribute.</param>
+		/// <param name="propertyValues">Values for the named properties of the custom attribute.</param>
+		public void SetCustomAttribute(
+			Type           attributeType,
+			PropertyInfo[] properties,
+			object[]       propertyValues)
+		{
+			if (attributeType == null) throw new ArgumentNullException("attributeType");
+
+			ConstructorInfo        ci        = attributeType.GetConstructor(Type.EmptyTypes);
+			CustomAttributeBuilder caBuilder = new CustomAttributeBuilder(
+				ci, new object[0], properties, propertyValues);
+
+			_typeBuilder.SetCustomAttribute(caBuilder);
+		}
+
+		/// <summary>
+		/// Sets a custom attribute using a custom attribute type
+		/// and named property.
+		/// </summary>
+		/// <param name="attributeType">Attribute type.</param>
+		/// <param name="propertyName">A named property of the custom attribute.</param>
+		/// <param name="propertyValue">Value for the named property of the custom attribute.</param>
+		public void SetCustomAttribute(
+			Type   attributeType,
+			string propertyName,
+			object propertyValue)
+		{
+			SetCustomAttribute(
+				attributeType,
+				new PropertyInfo[] { attributeType.GetProperty(propertyName) },
+				new object[]       { propertyValue } );
+		}
+
+		private ConstructorBuilderHelper _typeInitializer;
+		/// <summary>
+		/// Gets the initializer for this type.
+		/// </summary>
+		public ConstructorBuilderHelper TypeInitializer
+		{
+			get 
+			{
+				if (_typeInitializer == null)
+					_typeInitializer = new ConstructorBuilderHelper(this, _typeBuilder.DefineTypeInitializer());
+
+				return _typeInitializer;
+			}
+		}
+
+		/// <summary>
+		/// Returns true if the initializer for this type has a body.
+		/// </summary>
+		public bool IsTypeInitializerDefined
+		{
+			get { return _typeInitializer != null; }
+		}
+
+		private ConstructorBuilderHelper _defaultConstructor;
+		/// <summary>
+		/// Gets the default constructor for this type.
+		/// </summary>
+		public  ConstructorBuilderHelper  DefaultConstructor
+		{
+			get 
+			{
+				if (_defaultConstructor == null)
+				{
+					ConstructorBuilder builder = _typeBuilder.DefineConstructor(
+						MethodAttributes.Public,
+						CallingConventions.Standard,
+						Type.EmptyTypes);
+
+					_defaultConstructor = new ConstructorBuilderHelper(this, builder);
+				}
+
+				return _defaultConstructor;
+			}
+		}
+
+		/// <summary>
+		/// Returns true if the default constructor for this type has a body.
+		/// </summary>
+		public bool IsDefaultConstructorDefined
+		{
+			get { return _defaultConstructor != null; }
+		}
+
+		private ConstructorBuilderHelper _initConstructor;
+		/// <summary>
+		/// Gets the init context constructor for this type.
+		/// </summary>
+		public  ConstructorBuilderHelper  InitConstructor
+		{
+			get 
+			{
+				if (_initConstructor == null)
+				{
+					ConstructorBuilder builder = _typeBuilder.DefineConstructor(
+						MethodAttributes.Public, 
+						CallingConventions.Standard,
+						new Type[] { typeof(InitContext) });
+
+					_initConstructor = new ConstructorBuilderHelper(this, builder);
+				}
+
+				return _initConstructor;
+			}
+		}
+
+		/// <summary>
+		/// Returns true if a constructor with parameter of <see cref="InitContext"/> for this type has a body.
+		/// </summary>
+		public bool IsInitConstructorDefined
+		{
+			get { return _initConstructor != null; }
+		}
+
+		/// <summary>
+		/// Adds a new field to the class, with the given name, attributes and field type.
+		/// </summary>
+		/// <param name="fieldName">The name of the field. <paramref name="fieldName"/> cannot contain embedded nulls.</param>
+		/// <param name="type">The type of the field.</param>
+		/// <param name="attributes">The attributes of the field.</param>
+		/// <returns>The defined field.</returns>
+		public FieldBuilder DefineField(
+			string          fieldName,
+			Type            type,
+			FieldAttributes attributes)
+		{
+			return _typeBuilder.DefineField(fieldName, type, attributes);
+		}
+
+		#region DefineConstructor Overrides
+
+		/// <summary>
+		/// Adds a new public constructor to the class, with the given parameters.
+		/// </summary>
+		/// <param name="parameterTypes">The types of the parameters of the method.</param>
+		/// <returns>The defined constructor.</returns>
+		public ConstructorBuilderHelper DefinePublicConstructor(params Type[] parameterTypes)
+		{
+			return new ConstructorBuilderHelper(
+				this,
+				_typeBuilder.DefineConstructor(
+					MethodAttributes.Public, CallingConventions.Standard, parameterTypes));
+		}
+
+		/// <summary>
+		/// Adds a new constructor to the class, with the given attributes and parameters.
+		/// </summary>
+		/// <param name="attributes">The attributes of the field.</param>
+		/// <param name="callingConvention">The <see cref="CallingConventions">calling convention</see> of the method.</param>
+		/// <param name="parameterTypes">The types of the parameters of the method.</param>
+		/// <returns>The defined constructor.</returns>
+		public ConstructorBuilderHelper DefineConstructor(
+			MethodAttributes   attributes,
+			CallingConventions callingConvention,
+			params Type[]      parameterTypes)
+		{
+			return new ConstructorBuilderHelper(
+				this,
+				_typeBuilder.DefineConstructor(attributes, callingConvention, parameterTypes));
+		}
+
+		#endregion
+
+		#region DefineNestedType Overrides
+
+		/// <summary>
+		/// Defines a nested type given its name..
+		/// </summary>
+		/// <param name="name">The short name of the type.</param>
+		/// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
+		/// <seealso cref="System.Reflection.Emit.TypeBuilder.DefineNestedType(string)">
+		/// TypeBuilder.DefineNestedType Method</seealso>
+		public TypeBuilderHelper DefineNestedType(string name)
+		{
+			return new TypeBuilderHelper(_assembly, _typeBuilder.DefineNestedType(name));
+		}
+
+		/// <summary>
+		/// Defines a public nested type given its name and the type that it extends.
+		/// </summary>
+		/// <param name="name">The short name of the type.</param>
+		/// <param name="parent">The type that the nested type extends.</param>
+		/// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
+		/// <seealso cref="System.Reflection.Emit.TypeBuilder.DefineNestedType(string,TypeAttributes,Type)">
+		/// TypeBuilder.DefineNestedType Method</seealso>
+		public TypeBuilderHelper DefineNestedType(string name, Type parent)
+		{
+			return new TypeBuilderHelper(
+				_assembly,
+				_typeBuilder.DefineNestedType(name, TypeAttributes.NestedPublic, parent));
+		}
+
+		/// <summary>
+		/// Defines a nested type given its name, attributes, and the type that it extends.
+		/// </summary>
+		/// <param name="name">The short name of the type.</param>
+		/// <param name="attributes">The attributes of the type.</param>
+		/// <param name="parent">The type that the nested type extends.</param>
+		/// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
+		/// <seealso cref="System.Reflection.Emit.TypeBuilder.DefineNestedType(string,TypeAttributes,Type)">
+		/// TypeBuilder.DefineNestedType Method</seealso>
+		public TypeBuilderHelper DefineNestedType(
+			string         name,
+			TypeAttributes attributes,
+			Type           parent)
+		{
+			return new TypeBuilderHelper(
+				_assembly,
+				_typeBuilder.DefineNestedType(name, attributes, parent));
+		}
+
+		/// <summary>
+		/// Defines a public nested type given its name, the type that it extends, and the interfaces that it implements.
+		/// </summary>
+		/// <param name="name">The short name of the type.</param>
+		/// <param name="parent">The type that the nested type extends.</param>
+		/// <param name="interfaces">The interfaces that the nested type implements.</param>
+		/// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
+		/// <seealso cref="System.Reflection.Emit.TypeBuilder.DefineNestedType(string,TypeAttributes,Type,Type[])">
+		/// TypeBuilder.DefineNestedType Method</seealso>
+		public TypeBuilderHelper DefineNestedType(
+			string        name,
+			Type          parent,
+			params Type[] interfaces)
+		{
+			return new TypeBuilderHelper(
+				_assembly,
+				_typeBuilder.DefineNestedType(name, TypeAttributes.NestedPublic, parent, interfaces));
+		}
+
+		/// <summary>
+		/// Defines a nested type given its name, attributes, the type that it extends, and the interfaces that it implements.
+		/// </summary>
+		/// <param name="name">The short name of the type.</param>
+		/// <param name="attributes">The attributes of the type.</param>
+		/// <param name="parent">The type that the nested type extends.</param>
+		/// <param name="interfaces">The interfaces that the nested type implements.</param>
+		/// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
+		/// <seealso cref="System.Reflection.Emit.ModuleBuilder.DefineType(string,TypeAttributes,Type,Type[])">ModuleBuilder.DefineType Method</seealso>
+		public TypeBuilderHelper DefineNestedType(
+			string         name,
+			TypeAttributes attributes,
+			Type           parent,
+			params         Type[] interfaces)
+		{
+			return new TypeBuilderHelper(
+				_assembly,
+				_typeBuilder.DefineNestedType(name, attributes, parent, interfaces));
+		}
+
+		#endregion
+
+	}
+}