comparison Source/Reflection/Emit/TypeBuilderHelper.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.Collections.Generic;
3 using System.Reflection;
4 using System.Reflection.Emit;
5
6 namespace BLToolkit.Reflection.Emit
7 {
8 using TypeBuilder.Builders;
9
10 /// <summary>
11 /// A wrapper around the <see cref="TypeBuilder"/> class.
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.TypeBuilder">TypeBuilder Class</seealso>
16 public class TypeBuilderHelper
17 {
18 /// <summary>
19 /// Initializes a new instance of the <see cref="TypeBuilderHelper"/> class
20 /// with the specified parameters.
21 /// </summary>
22 /// <param name="assemblyBuilder">Associated <see cref="AssemblyBuilderHelper"/>.</param>
23 /// <param name="typeBuilder">A <see cref="TypeBuilder"/></param>
24 public TypeBuilderHelper(AssemblyBuilderHelper assemblyBuilder, System.Reflection.Emit.TypeBuilder typeBuilder)
25 {
26 if (assemblyBuilder == null) throw new ArgumentNullException("assemblyBuilder");
27 if (typeBuilder == null) throw new ArgumentNullException("typeBuilder");
28
29 _assembly = assemblyBuilder;
30 _typeBuilder = typeBuilder;
31
32 _typeBuilder.SetCustomAttribute(_assembly.BLToolkitAttribute);
33 }
34
35 private readonly AssemblyBuilderHelper _assembly;
36 /// <summary>
37 /// Gets associated <see cref="AssemblyBuilderHelper"/>.
38 /// </summary>
39 public AssemblyBuilderHelper Assembly
40 {
41 get { return _assembly; }
42 }
43
44 private readonly System.Reflection.Emit.TypeBuilder _typeBuilder;
45 /// <summary>
46 /// Gets <see cref="System.Reflection.Emit.TypeBuilder"/>.
47 /// </summary>
48 public System.Reflection.Emit.TypeBuilder TypeBuilder
49 {
50 get { return _typeBuilder; }
51 }
52
53 /// <summary>
54 /// Converts the supplied <see cref="TypeBuilderHelper"/> to a <see cref="TypeBuilder"/>.
55 /// </summary>
56 /// <param name="typeBuilder">The <see cref="TypeBuilderHelper"/>.</param>
57 /// <returns>A <see cref="TypeBuilder"/>.</returns>
58 public static implicit operator System.Reflection.Emit.TypeBuilder(TypeBuilderHelper typeBuilder)
59 {
60 if (typeBuilder == null) throw new ArgumentNullException("typeBuilder");
61
62 return typeBuilder.TypeBuilder;
63 }
64
65 #region DefineMethod Overrides
66
67 /// <summary>
68 /// Adds a new method to the class, with the given name and method signature.
69 /// </summary>
70 /// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
71 /// <param name="attributes">The attributes of the method. </param>
72 /// <param name="returnType">The return type of the method.</param>
73 /// <param name="parameterTypes">The types of the parameters of the method.</param>
74 /// <returns>The defined method.</returns>
75 public MethodBuilderHelper DefineMethod(
76 string name, MethodAttributes attributes, Type returnType, params Type[] parameterTypes)
77 {
78 return new MethodBuilderHelper(this, _typeBuilder.DefineMethod(name, attributes, returnType, parameterTypes));
79 }
80
81 /// <summary>
82 /// Adds a new method to the class, with the given name and method signature.
83 /// </summary>
84 /// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
85 /// <param name="attributes">The attributes of the method. </param>
86 /// <param name="callingConvention">The <see cref="CallingConventions">calling convention</see> of the method.</param>
87 /// <param name="returnType">The return type of the method.</param>
88 /// <param name="parameterTypes">The types of the parameters of the method.</param>
89 /// <returns>The defined method.</returns>
90 public MethodBuilderHelper DefineMethod(
91 string name,
92 MethodAttributes attributes,
93 CallingConventions callingConvention,
94 Type returnType,
95 Type[] parameterTypes)
96 {
97 return new MethodBuilderHelper(this, _typeBuilder.DefineMethod(
98 name, attributes, callingConvention, returnType, parameterTypes));
99 }
100
101 /// <summary>
102 /// Adds a new method to the class, with the given name and method signature.
103 /// </summary>
104 /// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
105 /// <param name="attributes">The attributes of the method. </param>
106 /// <param name="returnType">The return type of the method.</param>
107 /// <returns>The defined method.</returns>
108 public MethodBuilderHelper DefineMethod(string name, MethodAttributes attributes, Type returnType)
109 {
110 return new MethodBuilderHelper(
111 this,
112 _typeBuilder.DefineMethod(name, attributes, returnType, Type.EmptyTypes));
113 }
114
115 /// <summary>
116 /// Adds a new method to the class, with the given name and method signature.
117 /// </summary>
118 /// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
119 /// <param name="attributes">The attributes of the method. </param>
120 /// <returns>The defined method.</returns>
121 public MethodBuilderHelper DefineMethod(string name, MethodAttributes attributes)
122 {
123 return new MethodBuilderHelper(
124 this,
125 _typeBuilder.DefineMethod(name, attributes, typeof(void), Type.EmptyTypes));
126 }
127
128 /// <summary>
129 /// Adds a new method to the class, with the given name and method signature.
130 /// </summary>
131 /// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
132 /// <param name="attributes">The attributes of the method. </param>
133 /// <returns>The defined method.</returns>
134 /// <param name="callingConvention">The calling convention of the method.</param>
135 public MethodBuilderHelper DefineMethod(
136 string name,
137 MethodAttributes attributes,
138 CallingConventions callingConvention)
139 {
140 return new MethodBuilderHelper(
141 this,
142 _typeBuilder.DefineMethod(name, attributes, callingConvention));
143 }
144
145 /// <summary>
146 /// Adds a new method to the class, with the given name and method signature.
147 /// </summary>
148 /// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
149 /// <param name="attributes">The attributes of the method. </param>
150 /// <param name="callingConvention">The <see cref="CallingConventions">calling convention</see> of the method.</param>
151 /// <param name="genericArguments">Generic arguments of the method.</param>
152 /// <param name="returnType">The return type of the method.</param>
153 /// <param name="parameterTypes">The types of the parameters of the method.</param>
154 /// <returns>The defined generic method.</returns>
155 public MethodBuilderHelper DefineGenericMethod(
156 string name,
157 MethodAttributes attributes,
158 CallingConventions callingConvention,
159 Type[] genericArguments,
160 Type returnType,
161 Type[] parameterTypes)
162 {
163 return new MethodBuilderHelper(
164 this,
165 _typeBuilder.DefineMethod(name, attributes, callingConvention), genericArguments, returnType, parameterTypes);
166 }
167
168
169 private Dictionary<MethodInfo, MethodBuilder> _overriddenMethods;
170
171 /// <summary>
172 /// Retrieves the map of base type methods overridden by this type.
173 /// </summary>
174 public Dictionary<MethodInfo, MethodBuilder> OverriddenMethods
175 {
176 get { return _overriddenMethods ?? (_overriddenMethods = new Dictionary<MethodInfo,MethodBuilder>()); }
177 }
178
179 /// <summary>
180 /// Adds a new method to the class, with the given name and method signature.
181 /// </summary>
182 /// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
183 /// <param name="methodInfoDeclaration">The method whose declaration is to be used.</param>
184 /// <param name="attributes">The attributes of the method. </param>
185 /// <returns>The defined method.</returns>
186 public MethodBuilderHelper DefineMethod(
187 string name,
188 MethodInfo methodInfoDeclaration,
189 MethodAttributes attributes)
190 {
191 if (methodInfoDeclaration == null) throw new ArgumentNullException("methodInfoDeclaration");
192
193 MethodBuilderHelper method;
194 ParameterInfo[] pi = methodInfoDeclaration.GetParameters();
195 Type[] parameters = new Type[pi.Length];
196
197 for (int i = 0; i < pi.Length; i++)
198 parameters[i] = pi[i].ParameterType;
199
200 if (methodInfoDeclaration.ContainsGenericParameters)
201 {
202 method = DefineGenericMethod(
203 name,
204 attributes,
205 methodInfoDeclaration.CallingConvention,
206 methodInfoDeclaration.GetGenericArguments(),
207 methodInfoDeclaration.ReturnType,
208 parameters);
209 }
210 else
211 {
212 method = DefineMethod(
213 name,
214 attributes,
215 methodInfoDeclaration.CallingConvention,
216 methodInfoDeclaration.ReturnType,
217 parameters);
218 }
219
220 // Compiler overrides methods only for interfaces. We do the same.
221 // If we wanted to override virtual methods, then methods should've had
222 // MethodAttributes.VtableLayoutMask attribute
223 // and the following condition should've been used below:
224 // if ((methodInfoDeclaration is FakeMethodInfo) == false)
225 //
226 if (methodInfoDeclaration.DeclaringType.IsInterface
227 #if !SILVERLIGHT
228 && !(methodInfoDeclaration is FakeMethodInfo)
229 #endif
230 )
231 {
232 OverriddenMethods.Add(methodInfoDeclaration, method.MethodBuilder);
233 _typeBuilder.DefineMethodOverride(method.MethodBuilder, methodInfoDeclaration);
234 }
235
236 method.OverriddenMethod = methodInfoDeclaration;
237
238 for (int i = 0; i < pi.Length; i++)
239 method.MethodBuilder.DefineParameter(i + 1, pi[i].Attributes, pi[i].Name);
240
241 return method;
242 }
243
244 /// <summary>
245 /// Adds a new method to the class, with the given name and method signature.
246 /// </summary>
247 /// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
248 /// <param name="methodInfoDeclaration">The method whose declaration is to be used.</param>
249 /// <returns>The defined method.</returns>
250 public MethodBuilderHelper DefineMethod(string name, MethodInfo methodInfoDeclaration)
251 {
252 return DefineMethod(name, methodInfoDeclaration, MethodAttributes.Virtual);
253 }
254
255 /// <summary>
256 /// Adds a new private method to the class.
257 /// </summary>
258 /// <param name="methodInfoDeclaration">The method whose declaration is to be used.</param>
259 /// <returns>The defined method.</returns>
260 public MethodBuilderHelper DefineMethod(MethodInfo methodInfoDeclaration)
261 {
262 if (methodInfoDeclaration == null) throw new ArgumentNullException("methodInfoDeclaration");
263
264 var isInterface = methodInfoDeclaration.DeclaringType.IsInterface;
265 #if SILVERLIGHT
266 var isFake = false;
267 #else
268 var isFake = methodInfoDeclaration is FakeMethodInfo;
269 #endif
270
271 var name = isInterface && !isFake?
272 methodInfoDeclaration.DeclaringType.FullName + "." + methodInfoDeclaration.Name:
273 methodInfoDeclaration.Name;
274
275 var attributes =
276 MethodAttributes.Virtual |
277 MethodAttributes.HideBySig |
278 MethodAttributes.PrivateScope |
279 methodInfoDeclaration.Attributes & MethodAttributes.SpecialName;
280
281 if (isInterface && !isFake)
282 attributes |= MethodAttributes.Private;
283 else if ((attributes & MethodAttributes.SpecialName) != 0)
284 attributes |= MethodAttributes.Public;
285 else
286 attributes |= methodInfoDeclaration.Attributes &
287 (MethodAttributes.Public | MethodAttributes.Private);
288
289 return DefineMethod(name, methodInfoDeclaration, attributes);
290 }
291
292 #endregion
293
294 /// <summary>
295 /// Creates a Type object for the class.
296 /// </summary>
297 /// <returns>Returns the new Type object for this class.</returns>
298 public Type Create()
299 {
300 return TypeBuilder.CreateType();
301 }
302
303 /// <summary>
304 /// Sets a custom attribute using a custom attribute type.
305 /// </summary>
306 /// <param name="attributeType">Attribute type.</param>
307 public void SetCustomAttribute(Type attributeType)
308 {
309 if (attributeType == null) throw new ArgumentNullException("attributeType");
310
311 ConstructorInfo ci = attributeType.GetConstructor(Type.EmptyTypes);
312 CustomAttributeBuilder caBuilder = new CustomAttributeBuilder(ci, new object[0]);
313
314 _typeBuilder.SetCustomAttribute(caBuilder);
315 }
316
317 /// <summary>
318 /// Sets a custom attribute using a custom attribute type
319 /// and named properties.
320 /// </summary>
321 /// <param name="attributeType">Attribute type.</param>
322 /// <param name="properties">Named properties of the custom attribute.</param>
323 /// <param name="propertyValues">Values for the named properties of the custom attribute.</param>
324 public void SetCustomAttribute(
325 Type attributeType,
326 PropertyInfo[] properties,
327 object[] propertyValues)
328 {
329 if (attributeType == null) throw new ArgumentNullException("attributeType");
330
331 ConstructorInfo ci = attributeType.GetConstructor(Type.EmptyTypes);
332 CustomAttributeBuilder caBuilder = new CustomAttributeBuilder(
333 ci, new object[0], properties, propertyValues);
334
335 _typeBuilder.SetCustomAttribute(caBuilder);
336 }
337
338 /// <summary>
339 /// Sets a custom attribute using a custom attribute type
340 /// and named property.
341 /// </summary>
342 /// <param name="attributeType">Attribute type.</param>
343 /// <param name="propertyName">A named property of the custom attribute.</param>
344 /// <param name="propertyValue">Value for the named property of the custom attribute.</param>
345 public void SetCustomAttribute(
346 Type attributeType,
347 string propertyName,
348 object propertyValue)
349 {
350 SetCustomAttribute(
351 attributeType,
352 new PropertyInfo[] { attributeType.GetProperty(propertyName) },
353 new object[] { propertyValue } );
354 }
355
356 private ConstructorBuilderHelper _typeInitializer;
357 /// <summary>
358 /// Gets the initializer for this type.
359 /// </summary>
360 public ConstructorBuilderHelper TypeInitializer
361 {
362 get
363 {
364 if (_typeInitializer == null)
365 _typeInitializer = new ConstructorBuilderHelper(this, _typeBuilder.DefineTypeInitializer());
366
367 return _typeInitializer;
368 }
369 }
370
371 /// <summary>
372 /// Returns true if the initializer for this type has a body.
373 /// </summary>
374 public bool IsTypeInitializerDefined
375 {
376 get { return _typeInitializer != null; }
377 }
378
379 private ConstructorBuilderHelper _defaultConstructor;
380 /// <summary>
381 /// Gets the default constructor for this type.
382 /// </summary>
383 public ConstructorBuilderHelper DefaultConstructor
384 {
385 get
386 {
387 if (_defaultConstructor == null)
388 {
389 ConstructorBuilder builder = _typeBuilder.DefineConstructor(
390 MethodAttributes.Public,
391 CallingConventions.Standard,
392 Type.EmptyTypes);
393
394 _defaultConstructor = new ConstructorBuilderHelper(this, builder);
395 }
396
397 return _defaultConstructor;
398 }
399 }
400
401 /// <summary>
402 /// Returns true if the default constructor for this type has a body.
403 /// </summary>
404 public bool IsDefaultConstructorDefined
405 {
406 get { return _defaultConstructor != null; }
407 }
408
409 private ConstructorBuilderHelper _initConstructor;
410 /// <summary>
411 /// Gets the init context constructor for this type.
412 /// </summary>
413 public ConstructorBuilderHelper InitConstructor
414 {
415 get
416 {
417 if (_initConstructor == null)
418 {
419 ConstructorBuilder builder = _typeBuilder.DefineConstructor(
420 MethodAttributes.Public,
421 CallingConventions.Standard,
422 new Type[] { typeof(InitContext) });
423
424 _initConstructor = new ConstructorBuilderHelper(this, builder);
425 }
426
427 return _initConstructor;
428 }
429 }
430
431 /// <summary>
432 /// Returns true if a constructor with parameter of <see cref="InitContext"/> for this type has a body.
433 /// </summary>
434 public bool IsInitConstructorDefined
435 {
436 get { return _initConstructor != null; }
437 }
438
439 /// <summary>
440 /// Adds a new field to the class, with the given name, attributes and field type.
441 /// </summary>
442 /// <param name="fieldName">The name of the field. <paramref name="fieldName"/> cannot contain embedded nulls.</param>
443 /// <param name="type">The type of the field.</param>
444 /// <param name="attributes">The attributes of the field.</param>
445 /// <returns>The defined field.</returns>
446 public FieldBuilder DefineField(
447 string fieldName,
448 Type type,
449 FieldAttributes attributes)
450 {
451 return _typeBuilder.DefineField(fieldName, type, attributes);
452 }
453
454 #region DefineConstructor Overrides
455
456 /// <summary>
457 /// Adds a new public constructor to the class, with the given parameters.
458 /// </summary>
459 /// <param name="parameterTypes">The types of the parameters of the method.</param>
460 /// <returns>The defined constructor.</returns>
461 public ConstructorBuilderHelper DefinePublicConstructor(params Type[] parameterTypes)
462 {
463 return new ConstructorBuilderHelper(
464 this,
465 _typeBuilder.DefineConstructor(
466 MethodAttributes.Public, CallingConventions.Standard, parameterTypes));
467 }
468
469 /// <summary>
470 /// Adds a new constructor to the class, with the given attributes and parameters.
471 /// </summary>
472 /// <param name="attributes">The attributes of the field.</param>
473 /// <param name="callingConvention">The <see cref="CallingConventions">calling convention</see> of the method.</param>
474 /// <param name="parameterTypes">The types of the parameters of the method.</param>
475 /// <returns>The defined constructor.</returns>
476 public ConstructorBuilderHelper DefineConstructor(
477 MethodAttributes attributes,
478 CallingConventions callingConvention,
479 params Type[] parameterTypes)
480 {
481 return new ConstructorBuilderHelper(
482 this,
483 _typeBuilder.DefineConstructor(attributes, callingConvention, parameterTypes));
484 }
485
486 #endregion
487
488 #region DefineNestedType Overrides
489
490 /// <summary>
491 /// Defines a nested type given its name..
492 /// </summary>
493 /// <param name="name">The short name of the type.</param>
494 /// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
495 /// <seealso cref="System.Reflection.Emit.TypeBuilder.DefineNestedType(string)">
496 /// TypeBuilder.DefineNestedType Method</seealso>
497 public TypeBuilderHelper DefineNestedType(string name)
498 {
499 return new TypeBuilderHelper(_assembly, _typeBuilder.DefineNestedType(name));
500 }
501
502 /// <summary>
503 /// Defines a public nested type given its name and the type that it extends.
504 /// </summary>
505 /// <param name="name">The short name of the type.</param>
506 /// <param name="parent">The type that the nested type extends.</param>
507 /// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
508 /// <seealso cref="System.Reflection.Emit.TypeBuilder.DefineNestedType(string,TypeAttributes,Type)">
509 /// TypeBuilder.DefineNestedType Method</seealso>
510 public TypeBuilderHelper DefineNestedType(string name, Type parent)
511 {
512 return new TypeBuilderHelper(
513 _assembly,
514 _typeBuilder.DefineNestedType(name, TypeAttributes.NestedPublic, parent));
515 }
516
517 /// <summary>
518 /// Defines a nested type given its name, attributes, and the type that it extends.
519 /// </summary>
520 /// <param name="name">The short name of the type.</param>
521 /// <param name="attributes">The attributes of the type.</param>
522 /// <param name="parent">The type that the nested type extends.</param>
523 /// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
524 /// <seealso cref="System.Reflection.Emit.TypeBuilder.DefineNestedType(string,TypeAttributes,Type)">
525 /// TypeBuilder.DefineNestedType Method</seealso>
526 public TypeBuilderHelper DefineNestedType(
527 string name,
528 TypeAttributes attributes,
529 Type parent)
530 {
531 return new TypeBuilderHelper(
532 _assembly,
533 _typeBuilder.DefineNestedType(name, attributes, parent));
534 }
535
536 /// <summary>
537 /// Defines a public nested type given its name, the type that it extends, and the interfaces that it implements.
538 /// </summary>
539 /// <param name="name">The short name of the type.</param>
540 /// <param name="parent">The type that the nested type extends.</param>
541 /// <param name="interfaces">The interfaces that the nested type implements.</param>
542 /// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
543 /// <seealso cref="System.Reflection.Emit.TypeBuilder.DefineNestedType(string,TypeAttributes,Type,Type[])">
544 /// TypeBuilder.DefineNestedType Method</seealso>
545 public TypeBuilderHelper DefineNestedType(
546 string name,
547 Type parent,
548 params Type[] interfaces)
549 {
550 return new TypeBuilderHelper(
551 _assembly,
552 _typeBuilder.DefineNestedType(name, TypeAttributes.NestedPublic, parent, interfaces));
553 }
554
555 /// <summary>
556 /// Defines a nested type given its name, attributes, the type that it extends, and the interfaces that it implements.
557 /// </summary>
558 /// <param name="name">The short name of the type.</param>
559 /// <param name="attributes">The attributes of the type.</param>
560 /// <param name="parent">The type that the nested type extends.</param>
561 /// <param name="interfaces">The interfaces that the nested type implements.</param>
562 /// <returns>Returns the created <see cref="TypeBuilderHelper"/>.</returns>
563 /// <seealso cref="System.Reflection.Emit.ModuleBuilder.DefineType(string,TypeAttributes,Type,Type[])">ModuleBuilder.DefineType Method</seealso>
564 public TypeBuilderHelper DefineNestedType(
565 string name,
566 TypeAttributes attributes,
567 Type parent,
568 params Type[] interfaces)
569 {
570 return new TypeBuilderHelper(
571 _assembly,
572 _typeBuilder.DefineNestedType(name, attributes, parent, interfaces));
573 }
574
575 #endregion
576
577 }
578 }