diff Source/Reflection/Emit/AssemblyBuilderHelper.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/AssemblyBuilderHelper.cs	Thu Mar 27 21:46:09 2014 +0400
@@ -0,0 +1,315 @@
+using System;
+using System.Configuration.Assemblies;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Security;
+using System.Threading;
+
+namespace BLToolkit.Reflection.Emit
+{
+	/// <summary>
+	/// A wrapper around the <see cref="AssemblyBuilder"/> and <see cref="ModuleBuilder"/> classes.
+	/// </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.AssemblyBuilder">AssemblyBuilder Class</seealso>
+	/// <seealso cref="System.Reflection.Emit.ModuleBuilder">ModuleBuilder Class</seealso>
+	public class AssemblyBuilderHelper
+	{
+		/// <summary>
+		/// Initializes a new instance of the <see cref="AssemblyBuilderHelper"/> class
+		/// with the specified parameters.
+		/// </summary>
+		/// <param name="path">The path where the assembly will be saved.</param>
+		public AssemblyBuilderHelper(string path) : this(path, null, null)
+		{
+		}
+
+		/// <summary>
+		/// Initializes a new instance of the <see cref="AssemblyBuilderHelper"/> class
+		/// with the specified parameters.
+		/// </summary>
+		/// <param name="path">The path where the assembly will be saved.</param>
+		/// <param name="version">The assembly version.</param>
+		/// <param name="keyFile">The key pair file to sign the assembly.</param>
+		public AssemblyBuilderHelper(string path, Version version, string keyFile)
+		{
+			if (path == null) throw new ArgumentNullException("path");
+
+			var idx = path.IndexOf(',');
+
+			if (idx > 0)
+			{
+				path = path.Substring(0, idx);
+
+				if (path.Length >= 200)
+				{
+					idx = path.IndexOf('`');
+
+					if (idx > 0)
+					{
+						var idx2 = path.LastIndexOf('.');
+
+						if (idx2 > 0 && idx2 > idx)
+							path = path.Substring(0, idx + 1) + path.Substring(idx2 + 1);
+					}
+				}
+			}
+
+			path = path.Replace("+", ".").Replace("<", "_").Replace(">", "_");
+
+			if (path.Length >= 260)
+			{
+				path = path.Substring(0, 248);
+
+				for (var i = 0; i < int.MaxValue; i++)
+				{
+					var newPath = string.Format("{0}_{1:0000}.dll", path, i);
+
+					if (!System.IO.File.Exists(newPath))
+					{
+						path = newPath;
+						break;
+					}
+				}
+			}
+
+			var assemblyName = System.IO.Path.GetFileNameWithoutExtension(path);
+			var assemblyDir  = System.IO.Path.GetDirectoryName(path);
+
+			Path               = path;
+			_assemblyName.Name = assemblyName;
+
+			if (version != null)
+				_assemblyName.Version = version;
+
+#if !SILVERLIGHT
+
+			if (!string.IsNullOrEmpty(keyFile))
+			{
+				_assemblyName.Flags        |= AssemblyNameFlags.PublicKey;
+				_assemblyName.KeyPair       = new StrongNameKeyPair(System.IO.File.OpenRead(keyFile));
+				_assemblyName.HashAlgorithm = AssemblyHashAlgorithm.SHA1;
+			}
+
+#endif
+
+#if DEBUG
+			_assemblyName.Flags |= AssemblyNameFlags.EnableJITcompileTracking;
+#else
+			_assemblyName.Flags |= AssemblyNameFlags.EnableJITcompileOptimizer;
+#endif
+
+			_createAssemblyBuilder = _ =>
+			{
+#if SILVERLIGHT
+				_assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(_assemblyName, AssemblyBuilderAccess.Run);
+#else
+				_assemblyBuilder =
+					string.IsNullOrEmpty(assemblyDir)?
+					Thread.GetDomain().DefineDynamicAssembly(_assemblyName, AssemblyBuilderAccess.RunAndSave):
+					Thread.GetDomain().DefineDynamicAssembly(_assemblyName, AssemblyBuilderAccess.RunAndSave, assemblyDir);
+#endif
+
+				_assemblyBuilder.SetCustomAttribute(BLToolkitAttribute);
+
+#if !SILVERLIGHT
+
+				_assemblyBuilder.SetCustomAttribute(
+					new CustomAttributeBuilder(
+						typeof(AllowPartiallyTrustedCallersAttribute)
+							.GetConstructor(Type.EmptyTypes),
+						new object[0]));
+
+#endif
+			};
+		}
+
+		/// <summary>
+		/// Gets the path where the assembly will be saved.
+		/// </summary>
+		public string Path { get; private set; }
+
+		private readonly AssemblyName _assemblyName = new AssemblyName();
+		/// <summary>
+		/// Gets AssemblyName.
+		/// </summary>
+		public           AssemblyName  AssemblyName
+		{
+			get { return _assemblyName; }
+		}
+
+		readonly Action<int> _createAssemblyBuilder; 
+
+		AssemblyBuilder _assemblyBuilder;
+		/// <summary>
+		/// Gets AssemblyBuilder.
+		/// </summary>
+		public   AssemblyBuilder  AssemblyBuilder
+		{
+			get
+			{
+				if (_assemblyBuilder == null)
+					_createAssemblyBuilder(0);
+				return _assemblyBuilder;
+			}
+		}
+
+		/// <summary>
+		/// Gets the path where the assembly will be saved.
+		/// </summary>
+		public  string  ModulePath
+		{
+			get { return System.IO.Path.GetFileName(Path); }
+		}
+
+		private ModuleBuilder _moduleBuilder;
+		/// <summary>
+		/// Gets ModuleBuilder.
+		/// </summary>
+		public  ModuleBuilder  ModuleBuilder
+		{
+			get 
+			{
+				if (_moduleBuilder == null)
+				{
+					_moduleBuilder = AssemblyBuilder.DefineDynamicModule(ModulePath);
+					_moduleBuilder.SetCustomAttribute(BLToolkitAttribute);
+
+				}
+
+				return _moduleBuilder;
+			}
+		}
+
+		private CustomAttributeBuilder _blToolkitAttribute;
+		/// <summary>
+		/// Retrieves a cached instance of <see cref="BLToolkit.TypeBuilder.BLToolkitGeneratedAttribute"/> builder.
+		/// </summary>
+		public  CustomAttributeBuilder  BLToolkitAttribute
+		{
+			get 
+			{
+				if (_blToolkitAttribute == null)
+				{
+					var at = typeof(TypeBuilder.BLToolkitGeneratedAttribute);
+					var ci = at.GetConstructor(Type.EmptyTypes);
+
+					_blToolkitAttribute = new CustomAttributeBuilder(ci, new object[0]);
+				}
+
+				return _blToolkitAttribute;
+			}
+		}
+
+		/// <summary>
+		/// Converts the supplied <see cref="AssemblyBuilderHelper"/> to a <see cref="AssemblyBuilder"/>.
+		/// </summary>
+		/// <param name="assemblyBuilder">The <see cref="AssemblyBuilderHelper"/>.</param>
+		/// <returns>An <see cref="AssemblyBuilder"/>.</returns>
+		public static implicit operator AssemblyBuilder(AssemblyBuilderHelper assemblyBuilder)
+		{
+			if (assemblyBuilder == null) throw new ArgumentNullException("assemblyBuilder");
+
+			return assemblyBuilder.AssemblyBuilder;
+		}
+
+		/// <summary>
+		/// Converts the supplied <see cref="AssemblyBuilderHelper"/> to a <see cref="ModuleBuilder"/>.
+		/// </summary>
+		/// <param name="assemblyBuilder">The <see cref="AssemblyBuilderHelper"/>.</param>
+		/// <returns>A <see cref="ModuleBuilder"/>.</returns>
+		public static implicit operator ModuleBuilder(AssemblyBuilderHelper assemblyBuilder)
+		{
+			if (assemblyBuilder == null) throw new ArgumentNullException("assemblyBuilder");
+
+			return assemblyBuilder.ModuleBuilder;
+		}
+
+		/// <summary>
+		/// Saves this dynamic assembly to disk.
+		/// </summary>
+		public void Save()
+		{
+#if !SILVERLIGHT
+
+			if (_assemblyBuilder != null)
+				_assemblyBuilder.Save(ModulePath);
+
+#endif
+		}
+
+		#region DefineType Overrides
+
+		/// <summary>
+		/// Constructs a <see cref="TypeBuilderHelper"/> for a type with the specified name.
+		/// </summary>
+		/// <param name="name">The full path of the type.</param>
+		/// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
+		/// <seealso cref="System.Reflection.Emit.ModuleBuilder.DefineType(string)">ModuleBuilder.DefineType Method</seealso>
+		public TypeBuilderHelper DefineType(string name)
+		{
+			return new TypeBuilderHelper(this, ModuleBuilder.DefineType(name));
+		}
+
+		/// <summary>
+		/// Constructs a <see cref="TypeBuilderHelper"/> for a type with the specified name and base type.
+		/// </summary>
+		/// <param name="name">The full path of the type.</param>
+		/// <param name="parent">The Type that the defined type extends.</param>
+		/// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
+		/// <seealso cref="System.Reflection.Emit.ModuleBuilder.DefineType(string,TypeAttributes,Type)">ModuleBuilder.DefineType Method</seealso>
+		public TypeBuilderHelper DefineType(string name, Type parent)
+		{
+			return new TypeBuilderHelper(this, ModuleBuilder.DefineType(name, TypeAttributes.Public, parent));
+		}
+
+		/// <summary>
+		/// Constructs a <see cref="TypeBuilderHelper"/> for a type with the specified name, its attributes, and base type.
+		/// </summary>
+		/// <param name="name">The full path of the type.</param>
+		/// <param name="attrs">The attribute to be associated with the type.</param>
+		/// <param name="parent">The Type that the defined type extends.</param>
+		/// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
+		/// <seealso cref="System.Reflection.Emit.ModuleBuilder.DefineType(string,TypeAttributes,Type)">ModuleBuilder.DefineType Method</seealso>
+		public TypeBuilderHelper DefineType(string name, TypeAttributes attrs, Type parent)
+		{
+			return new TypeBuilderHelper(this, ModuleBuilder.DefineType(name, attrs, parent));
+		}
+
+		/// <summary>
+		/// Constructs a <see cref="TypeBuilderHelper"/> for a type with the specified name, base type,
+		/// and the interfaces that the defined type implements.
+		/// </summary>
+		/// <param name="name">The full path of the type.</param>
+		/// <param name="parent">The Type that the defined type extends.</param>
+		/// <param name="interfaces">The list of interfaces that the 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 DefineType(string name, Type parent, params Type[] interfaces)
+		{
+			return new TypeBuilderHelper(
+				this,
+				ModuleBuilder.DefineType(name, TypeAttributes.Public, parent, interfaces));
+		}
+
+		/// <summary>
+		/// Constructs a <see cref="TypeBuilderHelper"/> for a type with the specified name, its attributes, base type,
+		/// and the interfaces that the defined type implements.
+		/// </summary>
+		/// <param name="name">The full path of the type.</param>
+		/// <param name="attrs">The attribute to be associated with the type.</param>
+		/// <param name="parent">The Type that the defined type extends.</param>
+		/// <param name="interfaces">The list of interfaces that the 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 DefineType(string name, TypeAttributes attrs, Type parent, params Type[] interfaces)
+		{
+			return new TypeBuilderHelper(
+				this,
+				ModuleBuilder.DefineType(name, attrs, parent, interfaces));
+		}
+
+		#endregion
+	}
+}