Mercurial > pub > bltoolkit
view Source/Reflection/Emit/AssemblyBuilderHelper.cs @ 9:1e85f66cf767 default tip
update bltoolkit
author | nickolay |
---|---|
date | Thu, 05 Apr 2018 20:53:26 +0300 |
parents | f990fcb411a9 |
children |
line wrap: on
line source
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 } }