comparison Source/Reflection/Emit/AssemblyBuilderHelper.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f990fcb411a9
1 using System;
2 using System.Configuration.Assemblies;
3 using System.Reflection;
4 using System.Reflection.Emit;
5 using System.Security;
6 using System.Threading;
7
8 namespace BLToolkit.Reflection.Emit
9 {
10 /// <summary>
11 /// A wrapper around the <see cref="AssemblyBuilder"/> and <see cref="ModuleBuilder"/> classes.
12 /// </summary>
13 /// <include file="Examples.CS.xml" path='examples/emit[@name="Emit"]/*' />
14 /// <include file="Examples.VB.xml" path='examples/emit[@name="Emit"]/*' />
15 /// <seealso cref="System.Reflection.Emit.AssemblyBuilder">AssemblyBuilder Class</seealso>
16 /// <seealso cref="System.Reflection.Emit.ModuleBuilder">ModuleBuilder Class</seealso>
17 public class AssemblyBuilderHelper
18 {
19 /// <summary>
20 /// Initializes a new instance of the <see cref="AssemblyBuilderHelper"/> class
21 /// with the specified parameters.
22 /// </summary>
23 /// <param name="path">The path where the assembly will be saved.</param>
24 public AssemblyBuilderHelper(string path) : this(path, null, null)
25 {
26 }
27
28 /// <summary>
29 /// Initializes a new instance of the <see cref="AssemblyBuilderHelper"/> class
30 /// with the specified parameters.
31 /// </summary>
32 /// <param name="path">The path where the assembly will be saved.</param>
33 /// <param name="version">The assembly version.</param>
34 /// <param name="keyFile">The key pair file to sign the assembly.</param>
35 public AssemblyBuilderHelper(string path, Version version, string keyFile)
36 {
37 if (path == null) throw new ArgumentNullException("path");
38
39 var idx = path.IndexOf(',');
40
41 if (idx > 0)
42 {
43 path = path.Substring(0, idx);
44
45 if (path.Length >= 200)
46 {
47 idx = path.IndexOf('`');
48
49 if (idx > 0)
50 {
51 var idx2 = path.LastIndexOf('.');
52
53 if (idx2 > 0 && idx2 > idx)
54 path = path.Substring(0, idx + 1) + path.Substring(idx2 + 1);
55 }
56 }
57 }
58
59 path = path.Replace("+", ".").Replace("<", "_").Replace(">", "_");
60
61 if (path.Length >= 260)
62 {
63 path = path.Substring(0, 248);
64
65 for (var i = 0; i < int.MaxValue; i++)
66 {
67 var newPath = string.Format("{0}_{1:0000}.dll", path, i);
68
69 if (!System.IO.File.Exists(newPath))
70 {
71 path = newPath;
72 break;
73 }
74 }
75 }
76
77 var assemblyName = System.IO.Path.GetFileNameWithoutExtension(path);
78 var assemblyDir = System.IO.Path.GetDirectoryName(path);
79
80 Path = path;
81 _assemblyName.Name = assemblyName;
82
83 if (version != null)
84 _assemblyName.Version = version;
85
86 #if !SILVERLIGHT
87
88 if (!string.IsNullOrEmpty(keyFile))
89 {
90 _assemblyName.Flags |= AssemblyNameFlags.PublicKey;
91 _assemblyName.KeyPair = new StrongNameKeyPair(System.IO.File.OpenRead(keyFile));
92 _assemblyName.HashAlgorithm = AssemblyHashAlgorithm.SHA1;
93 }
94
95 #endif
96
97 #if DEBUG
98 _assemblyName.Flags |= AssemblyNameFlags.EnableJITcompileTracking;
99 #else
100 _assemblyName.Flags |= AssemblyNameFlags.EnableJITcompileOptimizer;
101 #endif
102
103 _createAssemblyBuilder = _ =>
104 {
105 #if SILVERLIGHT
106 _assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(_assemblyName, AssemblyBuilderAccess.Run);
107 #else
108 _assemblyBuilder =
109 string.IsNullOrEmpty(assemblyDir)?
110 Thread.GetDomain().DefineDynamicAssembly(_assemblyName, AssemblyBuilderAccess.RunAndSave):
111 Thread.GetDomain().DefineDynamicAssembly(_assemblyName, AssemblyBuilderAccess.RunAndSave, assemblyDir);
112 #endif
113
114 _assemblyBuilder.SetCustomAttribute(BLToolkitAttribute);
115
116 #if !SILVERLIGHT
117
118 _assemblyBuilder.SetCustomAttribute(
119 new CustomAttributeBuilder(
120 typeof(AllowPartiallyTrustedCallersAttribute)
121 .GetConstructor(Type.EmptyTypes),
122 new object[0]));
123
124 #endif
125 };
126 }
127
128 /// <summary>
129 /// Gets the path where the assembly will be saved.
130 /// </summary>
131 public string Path { get; private set; }
132
133 private readonly AssemblyName _assemblyName = new AssemblyName();
134 /// <summary>
135 /// Gets AssemblyName.
136 /// </summary>
137 public AssemblyName AssemblyName
138 {
139 get { return _assemblyName; }
140 }
141
142 readonly Action<int> _createAssemblyBuilder;
143
144 AssemblyBuilder _assemblyBuilder;
145 /// <summary>
146 /// Gets AssemblyBuilder.
147 /// </summary>
148 public AssemblyBuilder AssemblyBuilder
149 {
150 get
151 {
152 if (_assemblyBuilder == null)
153 _createAssemblyBuilder(0);
154 return _assemblyBuilder;
155 }
156 }
157
158 /// <summary>
159 /// Gets the path where the assembly will be saved.
160 /// </summary>
161 public string ModulePath
162 {
163 get { return System.IO.Path.GetFileName(Path); }
164 }
165
166 private ModuleBuilder _moduleBuilder;
167 /// <summary>
168 /// Gets ModuleBuilder.
169 /// </summary>
170 public ModuleBuilder ModuleBuilder
171 {
172 get
173 {
174 if (_moduleBuilder == null)
175 {
176 _moduleBuilder = AssemblyBuilder.DefineDynamicModule(ModulePath);
177 _moduleBuilder.SetCustomAttribute(BLToolkitAttribute);
178
179 }
180
181 return _moduleBuilder;
182 }
183 }
184
185 private CustomAttributeBuilder _blToolkitAttribute;
186 /// <summary>
187 /// Retrieves a cached instance of <see cref="BLToolkit.TypeBuilder.BLToolkitGeneratedAttribute"/> builder.
188 /// </summary>
189 public CustomAttributeBuilder BLToolkitAttribute
190 {
191 get
192 {
193 if (_blToolkitAttribute == null)
194 {
195 var at = typeof(TypeBuilder.BLToolkitGeneratedAttribute);
196 var ci = at.GetConstructor(Type.EmptyTypes);
197
198 _blToolkitAttribute = new CustomAttributeBuilder(ci, new object[0]);
199 }
200
201 return _blToolkitAttribute;
202 }
203 }
204
205 /// <summary>
206 /// Converts the supplied <see cref="AssemblyBuilderHelper"/> to a <see cref="AssemblyBuilder"/>.
207 /// </summary>
208 /// <param name="assemblyBuilder">The <see cref="AssemblyBuilderHelper"/>.</param>
209 /// <returns>An <see cref="AssemblyBuilder"/>.</returns>
210 public static implicit operator AssemblyBuilder(AssemblyBuilderHelper assemblyBuilder)
211 {
212 if (assemblyBuilder == null) throw new ArgumentNullException("assemblyBuilder");
213
214 return assemblyBuilder.AssemblyBuilder;
215 }
216
217 /// <summary>
218 /// Converts the supplied <see cref="AssemblyBuilderHelper"/> to a <see cref="ModuleBuilder"/>.
219 /// </summary>
220 /// <param name="assemblyBuilder">The <see cref="AssemblyBuilderHelper"/>.</param>
221 /// <returns>A <see cref="ModuleBuilder"/>.</returns>
222 public static implicit operator ModuleBuilder(AssemblyBuilderHelper assemblyBuilder)
223 {
224 if (assemblyBuilder == null) throw new ArgumentNullException("assemblyBuilder");
225
226 return assemblyBuilder.ModuleBuilder;
227 }
228
229 /// <summary>
230 /// Saves this dynamic assembly to disk.
231 /// </summary>
232 public void Save()
233 {
234 #if !SILVERLIGHT
235
236 if (_assemblyBuilder != null)
237 _assemblyBuilder.Save(ModulePath);
238
239 #endif
240 }
241
242 #region DefineType Overrides
243
244 /// <summary>
245 /// Constructs a <see cref="TypeBuilderHelper"/> for a type with the specified name.
246 /// </summary>
247 /// <param name="name">The full path of the type.</param>
248 /// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
249 /// <seealso cref="System.Reflection.Emit.ModuleBuilder.DefineType(string)">ModuleBuilder.DefineType Method</seealso>
250 public TypeBuilderHelper DefineType(string name)
251 {
252 return new TypeBuilderHelper(this, ModuleBuilder.DefineType(name));
253 }
254
255 /// <summary>
256 /// Constructs a <see cref="TypeBuilderHelper"/> for a type with the specified name and base type.
257 /// </summary>
258 /// <param name="name">The full path of the type.</param>
259 /// <param name="parent">The Type that the defined type extends.</param>
260 /// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
261 /// <seealso cref="System.Reflection.Emit.ModuleBuilder.DefineType(string,TypeAttributes,Type)">ModuleBuilder.DefineType Method</seealso>
262 public TypeBuilderHelper DefineType(string name, Type parent)
263 {
264 return new TypeBuilderHelper(this, ModuleBuilder.DefineType(name, TypeAttributes.Public, parent));
265 }
266
267 /// <summary>
268 /// Constructs a <see cref="TypeBuilderHelper"/> for a type with the specified name, its attributes, and base type.
269 /// </summary>
270 /// <param name="name">The full path of the type.</param>
271 /// <param name="attrs">The attribute to be associated with the type.</param>
272 /// <param name="parent">The Type that the defined type extends.</param>
273 /// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
274 /// <seealso cref="System.Reflection.Emit.ModuleBuilder.DefineType(string,TypeAttributes,Type)">ModuleBuilder.DefineType Method</seealso>
275 public TypeBuilderHelper DefineType(string name, TypeAttributes attrs, Type parent)
276 {
277 return new TypeBuilderHelper(this, ModuleBuilder.DefineType(name, attrs, parent));
278 }
279
280 /// <summary>
281 /// Constructs a <see cref="TypeBuilderHelper"/> for a type with the specified name, base type,
282 /// and the interfaces that the defined type implements.
283 /// </summary>
284 /// <param name="name">The full path of the type.</param>
285 /// <param name="parent">The Type that the defined type extends.</param>
286 /// <param name="interfaces">The list of interfaces that the type implements.</param>
287 /// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
288 /// <seealso cref="System.Reflection.Emit.ModuleBuilder.DefineType(string,TypeAttributes,Type,Type[])">ModuleBuilder.DefineType Method</seealso>
289 public TypeBuilderHelper DefineType(string name, Type parent, params Type[] interfaces)
290 {
291 return new TypeBuilderHelper(
292 this,
293 ModuleBuilder.DefineType(name, TypeAttributes.Public, parent, interfaces));
294 }
295
296 /// <summary>
297 /// Constructs a <see cref="TypeBuilderHelper"/> for a type with the specified name, its attributes, base type,
298 /// and the interfaces that the defined type implements.
299 /// </summary>
300 /// <param name="name">The full path of the type.</param>
301 /// <param name="attrs">The attribute to be associated with the type.</param>
302 /// <param name="parent">The Type that the defined type extends.</param>
303 /// <param name="interfaces">The list of interfaces that the type implements.</param>
304 /// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
305 /// <seealso cref="System.Reflection.Emit.ModuleBuilder.DefineType(string,TypeAttributes,Type,Type[])">ModuleBuilder.DefineType Method</seealso>
306 public TypeBuilderHelper DefineType(string name, TypeAttributes attrs, Type parent, params Type[] interfaces)
307 {
308 return new TypeBuilderHelper(
309 this,
310 ModuleBuilder.DefineType(name, attrs, parent, interfaces));
311 }
312
313 #endregion
314 }
315 }