4
using System.Runtime.InteropServices;
5
using System.Diagnostics;
6
using System.Collections;
7
using System.Threading;
8
using System.Reflection;
9
using System.Reflection.Emit;
11
internal class ProxyBuilder
13
private Service service= null;
14
private string pathName = null;
15
private Type type = null;
16
private Introspector introspector = null;
18
private static MethodInfo Service_NameMI = typeof(Service).GetMethod("get_Name",
20
private static MethodInfo Service_ConnectionMI = typeof(Service).GetMethod("get_Connection",
22
private static MethodInfo Service_AddSignalCalledMI = typeof(Service).GetMethod("add_SignalCalled",
23
new Type[] {typeof(Service.SignalCalledHandler)});
24
private static MethodInfo Service_RemoveSignalCalledMI = typeof(Service).GetMethod("remove_SignalCalled",
25
new Type[] {typeof(Service.SignalCalledHandler)});
26
private static MethodInfo Signal_PathNameMI = typeof(Signal).GetMethod("get_PathName",
28
private static MethodInfo Message_ArgumentsMI = typeof(Message).GetMethod("get_Arguments",
30
private static MethodInfo Message_KeyMI = typeof(Message).GetMethod("get_Key",
32
private static MethodInfo Arguments_InitAppendingMI = typeof(Arguments).GetMethod("InitAppending",
34
private static MethodInfo Arguments_AppendMI = typeof(Arguments).GetMethod("Append",
35
new Type[] {typeof(DBusType.IDBusType)});
36
private static MethodInfo Message_SendWithReplyAndBlockMI = typeof(Message).GetMethod("SendWithReplyAndBlock",
38
private static MethodInfo Message_SendMI = typeof(Message).GetMethod("Send",
40
private static MethodInfo Message_DisposeMI = typeof(Message).GetMethod("Dispose",
42
private static MethodInfo Arguments_GetEnumeratorMI = typeof(Arguments).GetMethod("GetEnumerator",
44
private static MethodInfo IEnumerator_MoveNextMI = typeof(System.Collections.IEnumerator).GetMethod("MoveNext",
46
private static MethodInfo IEnumerator_CurrentMI = typeof(System.Collections.IEnumerator).GetMethod("get_Current",
48
private static MethodInfo Type_GetTypeFromHandleMI = typeof(System.Type).GetMethod("GetTypeFromHandle",
49
new Type[] {typeof(System.RuntimeTypeHandle)});
50
private static MethodInfo IDBusType_GetMI = typeof(DBusType.IDBusType).GetMethod("Get",
51
new Type[] {typeof(System.Type)});
52
private static ConstructorInfo MethodCall_C = typeof(MethodCall).GetConstructor(new Type[] {typeof(Service),
56
private static ConstructorInfo Signal_C = typeof(Signal).GetConstructor(new Type[] {typeof(Service),
60
private static ConstructorInfo Service_SignalCalledHandlerC = typeof(Service.SignalCalledHandler).GetConstructor(new Type[] {typeof(object),
61
typeof(System.IntPtr)});
62
private static MethodInfo String_opEqualityMI = typeof(System.String).GetMethod("op_Equality",
63
new Type[] {typeof(string),
65
private static MethodInfo MulticastDelegate_opInequalityMI = typeof(System.MulticastDelegate).GetMethod("op_Inequality",
66
new Type[] {typeof(System.MulticastDelegate),
67
typeof(System.MulticastDelegate)});
70
public ProxyBuilder(Service service, Type type, string pathName)
72
this.service = service;
73
this.pathName = pathName;
75
this.introspector = Introspector.GetIntrospector(type);
78
private MethodInfo BuildSignalCalled(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF)
80
Type[] parTypes = {typeof(Signal)};
81
MethodBuilder methodBuilder = typeB.DefineMethod("Service_SignalCalled",
82
MethodAttributes.Private |
83
MethodAttributes.HideBySig,
87
ILGenerator generator = methodBuilder.GetILGenerator();
89
LocalBuilder enumeratorL = generator.DeclareLocal(typeof(System.Collections.IEnumerator));
90
enumeratorL.SetLocalSymInfo("enumerator");
92
Label wrongPath = generator.DefineLabel();
93
//generator.EmitWriteLine("if (signal.PathName == pathName) {");
94
generator.Emit(OpCodes.Ldarg_1);
95
generator.EmitCall(OpCodes.Callvirt, Signal_PathNameMI, null);
96
generator.Emit(OpCodes.Ldarg_0);
97
generator.Emit(OpCodes.Ldfld, pathF);
98
generator.EmitCall(OpCodes.Call, String_opEqualityMI, null);
99
generator.Emit(OpCodes.Brfalse, wrongPath);
103
foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
104
InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
105
foreach (DictionaryEntry signalEntry in interfaceProxy.Signals) {
106
EventInfo eventE = (EventInfo) signalEntry.Value;
107
// This is really cheeky since we need to grab the event as a private field.
108
FieldInfo eventF = this.type.GetField(eventE.Name,
109
BindingFlags.NonPublic|
110
BindingFlags.Instance);
112
MethodInfo eventHandler_InvokeMI = eventE.EventHandlerType.GetMethod("Invoke");
114
ParameterInfo[] pars = eventHandler_InvokeMI.GetParameters();
115
parTypes = new Type[pars.Length];
116
for (int parN = 0; parN < pars.Length; parN++) {
117
parTypes[parN] = pars[parN].ParameterType;
118
LocalBuilder parmL = generator.DeclareLocal(parTypes[parN]);
119
parmL.SetLocalSymInfo(pars[parN].Name);
122
Label skip = generator.DefineLabel();
123
//generator.EmitWriteLine(" if (SelectedIndexChanged != null) {");
124
generator.Emit(OpCodes.Ldarg_0);
125
generator.Emit(OpCodes.Ldfld, eventF);
126
generator.Emit(OpCodes.Ldnull);
127
generator.EmitCall(OpCodes.Call, MulticastDelegate_opInequalityMI, null);
128
generator.Emit(OpCodes.Brfalse, skip);
130
//generator.EmitWriteLine(" if (signal.Key == 'la i')");
131
generator.Emit(OpCodes.Ldarg_1);
132
generator.EmitCall(OpCodes.Callvirt, Message_KeyMI, null);
133
generator.Emit(OpCodes.Ldstr, eventE.Name + " " + InterfaceProxy.GetSignature(eventHandler_InvokeMI));
134
generator.EmitCall(OpCodes.Call, String_opEqualityMI, null);
135
generator.Emit(OpCodes.Brfalse, skip);
137
//generator.EmitWriteLine("IEnumerator enumerator = signal.Arguments.GetEnumerator()");
138
generator.Emit(OpCodes.Ldarg_1);
139
generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
140
generator.EmitCall(OpCodes.Callvirt, Arguments_GetEnumeratorMI, null);
141
generator.Emit(OpCodes.Stloc_0);
143
for (int parN = 0; parN < pars.Length; parN++) {
144
ParameterInfo par = pars[parN];
146
EmitSignalIn(generator, par.ParameterType, parN + localOffset, serviceF);
150
//generator.EmitWriteLine(" SelectedIndexChanged(selectedIndex)");
151
generator.Emit(OpCodes.Ldarg_0);
152
generator.Emit(OpCodes.Ldfld, eventF);
153
for (int parN = 0; parN < pars.Length; parN++) {
154
generator.Emit(OpCodes.Ldloc_S, parN + localOffset);
157
generator.EmitCall(OpCodes.Callvirt, eventHandler_InvokeMI, null);
159
generator.MarkLabel(skip);
160
//generator.EmitWriteLine(" }");
162
localOffset += pars.Length;
166
generator.MarkLabel(wrongPath);
167
//generator.EmitWriteLine("}");
169
//generator.EmitWriteLine("return");
170
generator.Emit(OpCodes.Ret);
172
return methodBuilder;
175
private void BuildSignalHandler(EventInfo eventE,
176
InterfaceProxy interfaceProxy,
177
ref TypeBuilder typeB,
181
MethodInfo eventHandler_InvokeMI = eventE.EventHandlerType.GetMethod("Invoke");
182
ParameterInfo[] pars = eventHandler_InvokeMI.GetParameters();
183
Type[] parTypes = new Type[pars.Length];
184
for (int parN = 0; parN < pars.Length; parN++) {
185
parTypes[parN] = pars[parN].ParameterType;
189
MethodBuilder methodBuilder = typeB.DefineMethod("Proxy_" + eventE.Name,
190
MethodAttributes.Public |
191
MethodAttributes.HideBySig |
192
MethodAttributes.Virtual,
195
ILGenerator generator = methodBuilder.GetILGenerator();
197
for (int parN = 0; parN < pars.Length; parN++) {
198
methodBuilder.DefineParameter(parN + 1, pars[parN].Attributes, pars[parN].Name);
201
// Generate the locals
202
LocalBuilder methodCallL = generator.DeclareLocal(typeof(MethodCall));
203
methodCallL.SetLocalSymInfo("signal");
205
//generator.EmitWriteLine("Signal signal = new Signal(...)");
206
generator.Emit(OpCodes.Ldsfld, serviceF);
207
generator.Emit(OpCodes.Ldarg_0);
208
generator.Emit(OpCodes.Ldfld, pathF);
209
generator.Emit(OpCodes.Ldstr, interfaceProxy.InterfaceName);
210
generator.Emit(OpCodes.Ldstr, eventE.Name);
211
generator.Emit(OpCodes.Newobj, Signal_C);
212
generator.Emit(OpCodes.Stloc_0);
214
//generator.EmitWriteLine("signal.Arguments.InitAppending()");
215
generator.Emit(OpCodes.Ldloc_0);
216
generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
217
generator.EmitCall(OpCodes.Callvirt, Arguments_InitAppendingMI, null);
219
for (int parN = 0; parN < pars.Length; parN++) {
220
ParameterInfo par = pars[parN];
222
EmitIn(generator, par.ParameterType, parN, serviceF);
226
//generator.EmitWriteLine("signal.Send()");
227
generator.Emit(OpCodes.Ldloc_0);
228
generator.EmitCall(OpCodes.Callvirt, Message_SendMI, null);
230
//generator.EmitWriteLine("signal.Dispose()");
231
generator.Emit(OpCodes.Ldloc_0);
232
generator.EmitCall(OpCodes.Callvirt, Message_DisposeMI, null);
234
//generator.EmitWriteLine("return");
235
generator.Emit(OpCodes.Ret);
238
private void BuildMethod(MethodInfo method,
239
InterfaceProxy interfaceProxy,
240
ref TypeBuilder typeB,
244
ParameterInfo[] pars = method.GetParameters();
245
Type[] parTypes = new Type[pars.Length];
246
for (int parN = 0; parN < pars.Length; parN++) {
247
parTypes[parN] = pars[parN].ParameterType;
251
MethodBuilder methodBuilder = typeB.DefineMethod(method.Name,
252
MethodAttributes.Public |
253
MethodAttributes.HideBySig |
254
MethodAttributes.Virtual,
257
ILGenerator generator = methodBuilder.GetILGenerator();
259
for (int parN = 0; parN < pars.Length; parN++) {
260
methodBuilder.DefineParameter(parN + 1, pars[parN].Attributes, pars[parN].Name);
263
// Generate the locals
264
LocalBuilder methodCallL = generator.DeclareLocal(typeof(MethodCall));
265
methodCallL.SetLocalSymInfo("methodCall");
266
LocalBuilder replyL = generator.DeclareLocal(typeof(MethodReturn));
267
replyL.SetLocalSymInfo("reply");
268
LocalBuilder enumeratorL = generator.DeclareLocal(typeof(System.Collections.IEnumerator));
269
enumeratorL.SetLocalSymInfo("enumerator");
271
if (method.ReturnType != typeof(void)) {
272
LocalBuilder retvalL = generator.DeclareLocal(method.ReturnType);
273
retvalL.SetLocalSymInfo("retval");
276
//generator.EmitWriteLine("MethodCall methodCall = new MethodCall(...)");
277
generator.Emit(OpCodes.Ldsfld, serviceF);
278
generator.Emit(OpCodes.Ldarg_0);
279
generator.Emit(OpCodes.Ldfld, pathF);
280
generator.Emit(OpCodes.Ldstr, interfaceProxy.InterfaceName);
281
generator.Emit(OpCodes.Ldstr, method.Name);
282
generator.Emit(OpCodes.Newobj, MethodCall_C);
283
generator.Emit(OpCodes.Stloc_0);
285
//generator.EmitWriteLine("methodCall.Arguments.InitAppending()");
286
generator.Emit(OpCodes.Ldloc_0);
287
generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
288
generator.EmitCall(OpCodes.Callvirt, Arguments_InitAppendingMI, null);
290
for (int parN = 0; parN < pars.Length; parN++) {
291
ParameterInfo par = pars[parN];
293
EmitIn(generator, par.ParameterType, parN, serviceF);
297
//generator.EmitWriteLine("MethodReturn reply = methodCall.SendWithReplyAndBlock()");
298
generator.Emit(OpCodes.Ldloc_0);
299
generator.EmitCall(OpCodes.Callvirt, Message_SendWithReplyAndBlockMI, null);
300
generator.Emit(OpCodes.Stloc_1);
302
//generator.EmitWriteLine("IEnumerator enumeartor = reply.Arguments.GetEnumerator()");
303
generator.Emit(OpCodes.Ldloc_1);
304
generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
305
generator.EmitCall(OpCodes.Callvirt, Arguments_GetEnumeratorMI, null);
306
generator.Emit(OpCodes.Stloc_2);
308
// handle the return value
309
if (method.ReturnType != typeof(void)) {
310
EmitOut(generator, method.ReturnType, 0);
313
for (int parN = 0; parN < pars.Length; parN++) {
314
ParameterInfo par = pars[parN];
315
if (par.IsOut || par.ParameterType.ToString().EndsWith("&")) {
316
EmitOut(generator, par.ParameterType, parN);
320
// Clean up after ourselves
321
//generator.EmitWriteLine("methodCall.Dispose()");
322
generator.Emit(OpCodes.Ldloc_0);
323
generator.EmitCall(OpCodes.Callvirt, Message_DisposeMI, null);
325
//generator.EmitWriteLine("reply.Dispose()");
326
generator.Emit(OpCodes.Ldloc_1);
327
generator.EmitCall(OpCodes.Callvirt, Message_DisposeMI, null);
329
if (method.ReturnType != typeof(void)) {
330
generator.Emit(OpCodes.Ldloc_3);
333
generator.Emit(OpCodes.Ret);
335
// Generate the method
336
typeB.DefineMethodOverride(methodBuilder, method);
339
private void EmitSignalIn(ILGenerator generator, Type parType, int parN, FieldInfo serviceF)
341
//generator.EmitWriteLine("enumerator.MoveNext()");
342
generator.Emit(OpCodes.Ldloc_0);
343
generator.EmitCall(OpCodes.Callvirt, IEnumerator_MoveNextMI, null);
345
Type outParType = Arguments.MatchType(parType);
346
//generator.EmitWriteLine("int selectedIndex = (int) ((DBusType.IDBusType) enumerator.Current).Get(typeof(int))");
347
generator.Emit(OpCodes.Pop);
348
generator.Emit(OpCodes.Ldloc_0);
349
generator.EmitCall(OpCodes.Callvirt, IEnumerator_CurrentMI, null);
350
generator.Emit(OpCodes.Castclass, typeof(DBusType.IDBusType));
351
generator.Emit(OpCodes.Ldtoken, parType);
352
generator.EmitCall(OpCodes.Call, Type_GetTypeFromHandleMI, null);
353
generator.EmitCall(OpCodes.Callvirt, IDBusType_GetMI, null);
354
// Call the DBusType EmitMarshalOut to make it emit itself
355
object[] pars = new object[] {generator, parType, true};
356
outParType.InvokeMember("EmitMarshalOut", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
357
generator.Emit(OpCodes.Stloc_S, parN);
361
private void EmitIn(ILGenerator generator, Type parType, int parN, FieldInfo serviceF)
363
Type inParType = Arguments.MatchType(parType);
364
//generator.EmitWriteLine("methodCall.Arguments.Append(...)");
365
generator.Emit(OpCodes.Ldloc_0);
366
generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
367
generator.Emit(OpCodes.Ldarg_S, parN + 1);
369
// Call the DBusType EmitMarshalIn to make it emit itself
370
object[] pars = new object[] {generator, parType};
371
inParType.InvokeMember("EmitMarshalIn", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
373
generator.Emit(OpCodes.Ldsfld, serviceF);
374
generator.Emit(OpCodes.Newobj, Arguments.GetDBusTypeConstructor(inParType, parType));
375
generator.EmitCall(OpCodes.Callvirt, Arguments_AppendMI, null);
378
private void EmitOut(ILGenerator generator, Type parType, int parN)
380
Type outParType = Arguments.MatchType(parType);
381
//generator.EmitWriteLine("enumerator.MoveNext()");
382
generator.Emit(OpCodes.Ldloc_2);
383
generator.EmitCall(OpCodes.Callvirt, IEnumerator_MoveNextMI, null);
385
//generator.EmitWriteLine("return (" + parType + ") ((DBusType.IDBusType) enumerator.Current).Get(typeof(" + parType + "))");
386
generator.Emit(OpCodes.Pop);
388
generator.Emit(OpCodes.Ldarg_S, parN + 1);
391
generator.Emit(OpCodes.Ldloc_2);
392
generator.EmitCall(OpCodes.Callvirt, IEnumerator_CurrentMI, null);
393
generator.Emit(OpCodes.Castclass, typeof(DBusType.IDBusType));
394
generator.Emit(OpCodes.Ldtoken, parType);
395
generator.EmitCall(OpCodes.Call, Type_GetTypeFromHandleMI, null);
396
generator.EmitCall(OpCodes.Callvirt, IDBusType_GetMI, null);
398
// Call the DBusType EmitMarshalOut to make it emit itself
399
object[] pars = new object[] {generator, parType, parN == 0};
400
outParType.InvokeMember("EmitMarshalOut", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
403
generator.Emit(OpCodes.Stloc_3);
407
public void BuildConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF, MethodInfo signalCalledMI, FieldInfo deleF)
409
Type[] pars = {typeof(Service), typeof(string)};
410
ConstructorBuilder constructor = typeB.DefineConstructor(MethodAttributes.RTSpecialName |
411
MethodAttributes.Public,
412
CallingConventions.Standard, pars);
414
ILGenerator generator = constructor.GetILGenerator();
416
LocalBuilder handlerL = generator.DeclareLocal (typeof (Service.SignalCalledHandler));
417
handlerL.SetLocalSymInfo ("handler");
419
generator.Emit(OpCodes.Ldarg_0);
420
generator.Emit(OpCodes.Call, this.introspector.Constructor);
421
//generator.EmitWriteLine("service = myService");
422
generator.Emit(OpCodes.Ldarg_1);
423
generator.Emit(OpCodes.Stsfld, serviceF);
424
//generator.EmitWriteLine("this.pathName = pathName");
425
generator.Emit(OpCodes.Ldarg_0);
426
generator.Emit(OpCodes.Ldarg_2);
427
generator.Emit(OpCodes.Stfld, pathF);
429
//generator.EmitWriteLine("handler = new Service.SignalCalledHandler(Service_SignalCalled)");
430
generator.Emit(OpCodes.Ldarg_1);
431
generator.Emit(OpCodes.Ldarg_0);
432
generator.Emit(OpCodes.Ldftn, signalCalledMI);
433
generator.Emit(OpCodes.Newobj, Service_SignalCalledHandlerC);
434
generator.Emit(OpCodes.Stloc_0);
436
//generator.EmitWriteLine("this.delegate_created = handler");
437
generator.Emit(OpCodes.Ldarg_0);
438
generator.Emit(OpCodes.Ldloc_0);
439
generator.Emit(OpCodes.Stfld, deleF);
441
//generator.EmitWriteLine("myService.SignalCalled += handler");
442
generator.Emit(OpCodes.Ldloc_0);
443
generator.EmitCall(OpCodes.Callvirt, Service_AddSignalCalledMI, null);
445
//generator.EmitWriteLine("return");
446
generator.Emit(OpCodes.Ret);
449
public void BuildSignalConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF)
451
Type[] pars = {typeof(Service), typeof(string)};
452
ConstructorBuilder constructor = typeB.DefineConstructor(MethodAttributes.RTSpecialName |
453
MethodAttributes.Public,
454
CallingConventions.Standard, pars);
456
ILGenerator generator = constructor.GetILGenerator();
457
generator.Emit(OpCodes.Ldarg_0);
458
generator.Emit(OpCodes.Call, this.introspector.Constructor);
459
//generator.EmitWriteLine("service = myService");
460
generator.Emit(OpCodes.Ldarg_1);
461
generator.Emit(OpCodes.Stsfld, serviceF);
462
//generator.EmitWriteLine("this.pathName = pathName");
463
generator.Emit(OpCodes.Ldarg_0);
464
generator.Emit(OpCodes.Ldarg_2);
465
generator.Emit(OpCodes.Stfld, pathF);
467
//generator.EmitWriteLine("return");
468
generator.Emit(OpCodes.Ret);
471
public void BuildFinalizer (TypeBuilder tb, FieldInfo serviceF, FieldInfo deleF)
473
// Note that this is a *HORRIBLE* example of how to build a finalizer
474
// It doesn't use the try/finally to chain to Object::Finalize. However,
475
// because that is always going to be a nop, lets just ignore that here.
476
// If you are trying to find the right code, look at what mcs does ;-).
478
MethodBuilder mb = tb.DefineMethod("Finalize",
479
MethodAttributes.Family |
480
MethodAttributes.HideBySig |
481
MethodAttributes.Virtual,
484
ILGenerator generator = mb.GetILGenerator();
486
//generator.EmitWriteLine("this.service.SignalCalled -= this.delegate_created");
487
generator.Emit (OpCodes.Ldarg_0);
488
generator.Emit (OpCodes.Ldfld, serviceF);
489
generator.Emit (OpCodes.Ldarg_0);
490
generator.Emit (OpCodes.Ldfld, deleF);
491
generator.EmitCall (OpCodes.Callvirt, Service_RemoveSignalCalledMI, null);
492
generator.Emit (OpCodes.Ret);
495
public object GetSignalProxy()
497
Type proxyType = Service.ProxyAssembly.GetType(ObjectName + ".SignalProxy");
499
if (proxyType == null) {
501
TypeBuilder typeB = Service.Module.DefineType(ObjectName + ".SignalProxy",
502
TypeAttributes.Public,
505
FieldBuilder serviceF = typeB.DefineField("service",
507
FieldAttributes.Private |
508
FieldAttributes.Static);
509
FieldBuilder pathF = typeB.DefineField("pathName",
511
FieldAttributes.Private);
513
BuildSignalConstructor(ref typeB, serviceF, pathF);
515
// Build the signal handlers
516
foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
517
InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
518
foreach (DictionaryEntry signalEntry in interfaceProxy.Signals) {
519
EventInfo eventE = (EventInfo) signalEntry.Value;
520
BuildSignalHandler(eventE, interfaceProxy, ref typeB, serviceF, pathF);
524
proxyType = typeB.CreateType();
526
// Uncomment the following line to produce a DLL of the
527
// constructed assembly which can then be examined using
528
// monodis. Note that in order for this to work you should copy
529
// the client assembly as a dll file so that monodis can pick it
531
//Service.ProxyAssembly.Save("proxy.dll");
534
Type [] parTypes = new Type[] {typeof(Service), typeof(string)};
535
object [] pars = new object[] {Service, pathName};
537
ConstructorInfo constructor = proxyType.GetConstructor(parTypes);
538
object instance = constructor.Invoke(pars);
543
public object GetProxy()
545
Type proxyType = Service.ProxyAssembly.GetType(ObjectName + ".Proxy");
547
if (proxyType == null) {
549
TypeBuilder typeB = Service.Module.DefineType(ObjectName + ".Proxy", TypeAttributes.Public, this.type);
551
FieldBuilder serviceF = typeB.DefineField("service",
553
FieldAttributes.Private |
554
FieldAttributes.Static);
555
FieldBuilder pathF = typeB.DefineField("pathName",
557
FieldAttributes.Private);
558
FieldBuilder deleF = typeB.DefineField("delegate_created",
559
typeof(Service.SignalCalledHandler),
560
FieldAttributes.Private);
561
BuildFinalizer (typeB, serviceF, deleF);
563
MethodInfo signalCalledMI = BuildSignalCalled(ref typeB, serviceF, pathF);
564
BuildConstructor(ref typeB, serviceF, pathF, signalCalledMI, deleF);
567
foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
568
InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
569
foreach (DictionaryEntry methodEntry in interfaceProxy.Methods) {
570
MethodInfo method = (MethodInfo) methodEntry.Value;
571
BuildMethod(method, interfaceProxy, ref typeB, serviceF, pathF);
575
proxyType = typeB.CreateType();
577
// Uncomment the following line to produce a DLL of the
578
// constructed assembly which can then be examined using
579
// monodis. Note that in order for this to work you should copy
580
// the client assembly as a dll file so that monodis can pick it
582
//Service.ProxyAssembly.Save(Service.Name + ".proxy.dll");
585
Type [] parTypes = new Type[] {typeof(Service), typeof(string)};
586
object [] pars = new object[] {Service, pathName};
588
ConstructorInfo constructor = proxyType.GetConstructor(parTypes);
589
object instance = constructor.Invoke(pars);
593
private Service Service
600
private string ObjectName
603
return this.introspector.ToString();