* qt/Makfile.am:
[platform/upstream/dbus.git] / mono / ProxyBuilder.cs
index 8e170c7..7a3de95 100644 (file)
@@ -14,20 +14,31 @@ namespace DBus
     private string pathName = null;
     private Type type = null;
     private Introspector introspector = null;
-    private AssemblyBuilder proxyAssembly;
     
     private static MethodInfo Service_NameMI = typeof(Service).GetMethod("get_Name", 
                                                                            new Type[0]);
     private static MethodInfo Service_ConnectionMI = typeof(Service).GetMethod("get_Connection",
                                                                                  new Type[0]);
+    private static MethodInfo Service_AddSignalCalledMI = typeof(Service).GetMethod("add_SignalCalled",
+                                                                                   new Type[] {typeof(Service.SignalCalledHandler)});
+    private static MethodInfo Service_RemoveSignalCalledMI = typeof(Service).GetMethod("remove_SignalCalled",
+                                                                                   new Type[] {typeof(Service.SignalCalledHandler)});                                                                              
+    private static MethodInfo Signal_PathNameMI = typeof(Signal).GetMethod("get_PathName",
+                                                                          new Type[0]);
     private static MethodInfo Message_ArgumentsMI = typeof(Message).GetMethod("get_Arguments",
                                                                                 new Type[0]);
+    private static MethodInfo Message_KeyMI = typeof(Message).GetMethod("get_Key",
+                                                                       new Type[0]);
     private static MethodInfo Arguments_InitAppendingMI = typeof(Arguments).GetMethod("InitAppending",
                                                                                          new Type[0]);
     private static MethodInfo Arguments_AppendMI = typeof(Arguments).GetMethod("Append",
                                                                                  new Type[] {typeof(DBusType.IDBusType)});
     private static MethodInfo Message_SendWithReplyAndBlockMI = typeof(Message).GetMethod("SendWithReplyAndBlock",
                                                                                             new Type[0]);
+    private static MethodInfo Message_SendMI = typeof(Message).GetMethod("Send",
+                                                                        new Type[0]);
+    private static MethodInfo Message_DisposeMI = typeof(Message).GetMethod("Dispose",
+                                                                           new Type[0]);
     private static MethodInfo Arguments_GetEnumeratorMI = typeof(Arguments).GetMethod("GetEnumerator",
                                                                                          new Type[0]);
     private static MethodInfo IEnumerator_MoveNextMI = typeof(System.Collections.IEnumerator).GetMethod("MoveNext",
@@ -42,21 +53,192 @@ namespace DBus
                                                                                                typeof(string),
                                                                                                typeof(string),
                                                                                                typeof(string)});
+    private static ConstructorInfo Signal_C = typeof(Signal).GetConstructor(new Type[] {typeof(Service),
+                                                                                       typeof(string),
+                                                                                       typeof(string),
+                                                                                       typeof(string)});
+    private static ConstructorInfo Service_SignalCalledHandlerC = typeof(Service.SignalCalledHandler).GetConstructor(new Type[] {typeof(object),
+                                                                                                                                typeof(System.IntPtr)});
+    private static MethodInfo String_opEqualityMI = typeof(System.String).GetMethod("op_Equality",
+                                                                                   new Type[] {typeof(string),
+                                                                                               typeof(string)});                                                                                                            
+    private static MethodInfo MulticastDelegate_opInequalityMI = typeof(System.MulticastDelegate).GetMethod("op_Inequality",
+                                                                                   new Type[] {typeof(System.MulticastDelegate),
+                                                                                               typeof(System.MulticastDelegate)});
     
-                                                                                       
 
     public ProxyBuilder(Service service, Type type, string pathName)
     {
       this.service = service;
       this.pathName = pathName;
       this.type = type;
-      this.introspector = new Introspector(type);
+      this.introspector = Introspector.GetIntrospector(type);
+    }
+
+    private MethodInfo BuildSignalCalled(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF)
+    {
+      Type[] parTypes = {typeof(Signal)};
+      MethodBuilder methodBuilder = typeB.DefineMethod("Service_SignalCalled",
+                                                      MethodAttributes.Private |
+                                                      MethodAttributes.HideBySig,
+                                                      typeof(void),
+                                                      parTypes);
+      
+      ILGenerator generator = methodBuilder.GetILGenerator();
+
+      LocalBuilder enumeratorL = generator.DeclareLocal(typeof(System.Collections.IEnumerator));
+      enumeratorL.SetLocalSymInfo("enumerator");
+
+      Label wrongPath = generator.DefineLabel();
+      //generator.EmitWriteLine("if (signal.PathName == pathName) {");
+      generator.Emit(OpCodes.Ldarg_1);
+      generator.EmitCall(OpCodes.Callvirt, Signal_PathNameMI, null);
+      generator.Emit(OpCodes.Ldarg_0);
+      generator.Emit(OpCodes.Ldfld, pathF);
+      generator.EmitCall(OpCodes.Call, String_opEqualityMI, null);
+      generator.Emit(OpCodes.Brfalse, wrongPath);
+
+      int localOffset = 1;
+
+      foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
+       InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
+       foreach (DictionaryEntry signalEntry in interfaceProxy.Signals) {
+         EventInfo eventE = (EventInfo) signalEntry.Value;
+         // This is really cheeky since we need to grab the event as a private field.
+         FieldInfo eventF = this.type.GetField(eventE.Name,
+                                               BindingFlags.NonPublic|
+                                               BindingFlags.Instance);
+
+         MethodInfo eventHandler_InvokeMI = eventE.EventHandlerType.GetMethod("Invoke");
+
+         ParameterInfo[] pars = eventHandler_InvokeMI.GetParameters();
+         parTypes = new Type[pars.Length];
+         for (int parN = 0; parN < pars.Length; parN++) {
+           parTypes[parN] = pars[parN].ParameterType;
+           LocalBuilder parmL = generator.DeclareLocal(parTypes[parN]);
+           parmL.SetLocalSymInfo(pars[parN].Name);
+         }
+         
+         Label skip = generator.DefineLabel();      
+         //generator.EmitWriteLine("  if (SelectedIndexChanged != null) {");
+         generator.Emit(OpCodes.Ldarg_0);
+         generator.Emit(OpCodes.Ldfld, eventF);
+         generator.Emit(OpCodes.Ldnull);
+         generator.EmitCall(OpCodes.Call, MulticastDelegate_opInequalityMI, null);
+         generator.Emit(OpCodes.Brfalse, skip);
+         
+         //generator.EmitWriteLine("    if (signal.Key == 'la i')");
+         generator.Emit(OpCodes.Ldarg_1);
+         generator.EmitCall(OpCodes.Callvirt, Message_KeyMI, null);
+         generator.Emit(OpCodes.Ldstr, eventE.Name + " " + InterfaceProxy.GetSignature(eventHandler_InvokeMI));
+         generator.EmitCall(OpCodes.Call, String_opEqualityMI, null);
+         generator.Emit(OpCodes.Brfalse, skip);
+
+         //generator.EmitWriteLine("IEnumerator enumerator = signal.Arguments.GetEnumerator()");
+         generator.Emit(OpCodes.Ldarg_1);
+         generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
+         generator.EmitCall(OpCodes.Callvirt, Arguments_GetEnumeratorMI, null);
+         generator.Emit(OpCodes.Stloc_0);
+         
+         for (int parN = 0; parN < pars.Length; parN++) {
+           ParameterInfo par = pars[parN];
+           if (!par.IsOut) {
+             EmitSignalIn(generator, par.ParameterType, parN + localOffset, serviceF);
+           }
+         }
+         
+         //generator.EmitWriteLine("    SelectedIndexChanged(selectedIndex)");
+         generator.Emit(OpCodes.Ldarg_0);
+         generator.Emit(OpCodes.Ldfld, eventF);
+         for (int parN = 0; parN < pars.Length; parN++) {
+           generator.Emit(OpCodes.Ldloc_S, parN + localOffset);
+         }
+         
+         generator.EmitCall(OpCodes.Callvirt, eventHandler_InvokeMI, null);
+         
+         generator.MarkLabel(skip);
+         //generator.EmitWriteLine("  }");
+         
+         localOffset += pars.Length;
+       }
+      }
+
+      generator.MarkLabel(wrongPath);
+      //generator.EmitWriteLine("}");
+
+      //generator.EmitWriteLine("return");
+      generator.Emit(OpCodes.Ret);
+
+      return methodBuilder;
+    }
+    
+    private void BuildSignalHandler(EventInfo eventE, 
+                                   InterfaceProxy interfaceProxy,
+                                   ref TypeBuilder typeB, 
+                                   FieldInfo serviceF,
+                                   FieldInfo pathF)
+    {
+      MethodInfo eventHandler_InvokeMI = eventE.EventHandlerType.GetMethod("Invoke");
+      ParameterInfo[] pars = eventHandler_InvokeMI.GetParameters();
+      Type[] parTypes = new Type[pars.Length];
+      for (int parN = 0; parN < pars.Length; parN++) {
+       parTypes[parN] = pars[parN].ParameterType;
+      }
+
+      // Generate the code
+      MethodBuilder methodBuilder = typeB.DefineMethod("Proxy_" + eventE.Name, 
+                                                      MethodAttributes.Public |
+                                                      MethodAttributes.HideBySig |
+                                                      MethodAttributes.Virtual, 
+                                                      typeof(void),
+                                                      parTypes);
+      ILGenerator generator = methodBuilder.GetILGenerator();
+
+      for (int parN = 0; parN < pars.Length; parN++) {
+       methodBuilder.DefineParameter(parN + 1, pars[parN].Attributes, pars[parN].Name);
+      }
+
+      // Generate the locals
+      LocalBuilder methodCallL = generator.DeclareLocal(typeof(MethodCall));
+      methodCallL.SetLocalSymInfo("signal");
+
+      //generator.EmitWriteLine("Signal signal = new Signal(...)");
+      generator.Emit(OpCodes.Ldsfld, serviceF);
+      generator.Emit(OpCodes.Ldarg_0);
+      generator.Emit(OpCodes.Ldfld, pathF);
+      generator.Emit(OpCodes.Ldstr, interfaceProxy.InterfaceName);
+      generator.Emit(OpCodes.Ldstr, eventE.Name);
+      generator.Emit(OpCodes.Newobj, Signal_C);
+      generator.Emit(OpCodes.Stloc_0);
+
+      //generator.EmitWriteLine("signal.Arguments.InitAppending()");
+      generator.Emit(OpCodes.Ldloc_0);
+      generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
+      generator.EmitCall(OpCodes.Callvirt, Arguments_InitAppendingMI, null);
+
+      for (int parN = 0; parN < pars.Length; parN++) {
+       ParameterInfo par = pars[parN];
+       if (!par.IsOut) {
+         EmitIn(generator, par.ParameterType, parN, serviceF);
+       }
+      }
+      
+      //generator.EmitWriteLine("signal.Send()");
+      generator.Emit(OpCodes.Ldloc_0);
+      generator.EmitCall(OpCodes.Callvirt, Message_SendMI, null); 
+
+      //generator.EmitWriteLine("signal.Dispose()");
+      generator.Emit(OpCodes.Ldloc_0);
+      generator.EmitCall(OpCodes.Callvirt, Message_DisposeMI, null);
+
+      //generator.EmitWriteLine("return");
+      generator.Emit(OpCodes.Ret);
     }
 
     private void BuildMethod(MethodInfo method, 
+                            InterfaceProxy interfaceProxy,
                             ref TypeBuilder typeB, 
                             FieldInfo serviceF,
-                            FieldInfo interfaceF,
                             FieldInfo pathF)
     {
       ParameterInfo[] pars = method.GetParameters();
@@ -95,7 +277,7 @@ namespace DBus
       generator.Emit(OpCodes.Ldsfld, serviceF);
       generator.Emit(OpCodes.Ldarg_0);
       generator.Emit(OpCodes.Ldfld, pathF);
-      generator.Emit(OpCodes.Ldsfld, interfaceF);
+      generator.Emit(OpCodes.Ldstr, interfaceProxy.InterfaceName);
       generator.Emit(OpCodes.Ldstr, method.Name);
       generator.Emit(OpCodes.Newobj, MethodCall_C);
       generator.Emit(OpCodes.Stloc_0);
@@ -108,7 +290,7 @@ namespace DBus
       for (int parN = 0; parN < pars.Length; parN++) {
        ParameterInfo par = pars[parN];
        if (!par.IsOut) {
-         EmitIn(generator, par.ParameterType, parN);
+         EmitIn(generator, par.ParameterType, parN, serviceF);
        }
       }
       
@@ -135,6 +317,15 @@ namespace DBus
        }
       }
 
+      // Clean up after ourselves
+      //generator.EmitWriteLine("methodCall.Dispose()");
+      generator.Emit(OpCodes.Ldloc_0);
+      generator.EmitCall(OpCodes.Callvirt, Message_DisposeMI, null);
+
+      //generator.EmitWriteLine("reply.Dispose()");
+      generator.Emit(OpCodes.Ldloc_1);
+      generator.EmitCall(OpCodes.Callvirt, Message_DisposeMI, null);
+
       if (method.ReturnType != typeof(void)) {
        generator.Emit(OpCodes.Ldloc_3);
       }
@@ -145,7 +336,29 @@ namespace DBus
       typeB.DefineMethodOverride(methodBuilder, method);
     }
 
-    private void EmitIn(ILGenerator generator, Type parType, int parN)
+    private void EmitSignalIn(ILGenerator generator, Type parType, int parN, FieldInfo serviceF)
+    {
+       //generator.EmitWriteLine("enumerator.MoveNext()");
+       generator.Emit(OpCodes.Ldloc_0);
+       generator.EmitCall(OpCodes.Callvirt, IEnumerator_MoveNextMI, null);
+       
+       Type outParType = Arguments.MatchType(parType);
+       //generator.EmitWriteLine("int selectedIndex = (int) ((DBusType.IDBusType) enumerator.Current).Get(typeof(int))");
+       generator.Emit(OpCodes.Pop);
+       generator.Emit(OpCodes.Ldloc_0);
+       generator.EmitCall(OpCodes.Callvirt, IEnumerator_CurrentMI, null);
+       generator.Emit(OpCodes.Castclass, typeof(DBusType.IDBusType));
+       generator.Emit(OpCodes.Ldtoken, parType);
+       generator.EmitCall(OpCodes.Call, Type_GetTypeFromHandleMI, null);
+       generator.EmitCall(OpCodes.Callvirt, IDBusType_GetMI, null);
+       // Call the DBusType EmitMarshalOut to make it emit itself
+       object[] pars = new object[] {generator, parType, true};
+       outParType.InvokeMember("EmitMarshalOut", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
+       generator.Emit(OpCodes.Stloc_S, parN);
+    }
+    
+
+    private void EmitIn(ILGenerator generator, Type parType, int parN, FieldInfo serviceF)
     {
       Type inParType = Arguments.MatchType(parType);
       //generator.EmitWriteLine("methodCall.Arguments.Append(...)");
@@ -157,6 +370,7 @@ namespace DBus
       object[] pars = new object[] {generator, parType};
       inParType.InvokeMember("EmitMarshalIn", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
 
+      generator.Emit(OpCodes.Ldsfld, serviceF);
       generator.Emit(OpCodes.Newobj, Arguments.GetDBusTypeConstructor(inParType, parType));
       generator.EmitCall(OpCodes.Callvirt, Arguments_AppendMI, null);
     }
@@ -190,111 +404,204 @@ namespace DBus
       }
     }
     
-    public void BuildConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo interfaceF, FieldInfo pathF)
+    public void BuildConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF, MethodInfo signalCalledMI, FieldInfo deleF)
     {
-      Type[] pars = {typeof(Service), typeof(string), typeof(string)};
+      Type[] pars = {typeof(Service), typeof(string)};
       ConstructorBuilder constructor = typeB.DefineConstructor(MethodAttributes.RTSpecialName | 
                                                               MethodAttributes.Public,
                                                               CallingConventions.Standard, pars);
 
       ILGenerator generator = constructor.GetILGenerator();
+
+      LocalBuilder handlerL = generator.DeclareLocal (typeof (Service.SignalCalledHandler));
+      handlerL.SetLocalSymInfo ("handler");
+
       generator.Emit(OpCodes.Ldarg_0);
       generator.Emit(OpCodes.Call, this.introspector.Constructor);
+      //generator.EmitWriteLine("service = myService");
       generator.Emit(OpCodes.Ldarg_1);
       generator.Emit(OpCodes.Stsfld, serviceF);
-      generator.Emit(OpCodes.Ldarg_2);
-      generator.Emit(OpCodes.Stsfld, interfaceF);
+      //generator.EmitWriteLine("this.pathName = pathName");
       generator.Emit(OpCodes.Ldarg_0);
-      generator.Emit(OpCodes.Ldarg_3);
+      generator.Emit(OpCodes.Ldarg_2);
       generator.Emit(OpCodes.Stfld, pathF);
 
+      //generator.EmitWriteLine("handler = new Service.SignalCalledHandler(Service_SignalCalled)");      
+      generator.Emit(OpCodes.Ldarg_1);
+      generator.Emit(OpCodes.Ldarg_0);
+      generator.Emit(OpCodes.Ldftn, signalCalledMI);
+      generator.Emit(OpCodes.Newobj, Service_SignalCalledHandlerC);
+      generator.Emit(OpCodes.Stloc_0);
+
+      //generator.EmitWriteLine("this.delegate_created = handler");
+      generator.Emit(OpCodes.Ldarg_0);
+      generator.Emit(OpCodes.Ldloc_0);
+      generator.Emit(OpCodes.Stfld, deleF);
+
+      //generator.EmitWriteLine("myService.SignalCalled += handler");
+      generator.Emit(OpCodes.Ldloc_0);
+      generator.EmitCall(OpCodes.Callvirt, Service_AddSignalCalledMI, null);
+
+      //generator.EmitWriteLine("return");
       generator.Emit(OpCodes.Ret);
     }
-    
-    public object GetProxy() 
-    {      
-      
-      // Build the type
-      TypeBuilder typeB = ServiceModuleBuilder.DefineType(ProxyName, TypeAttributes.Public, this.type);
-      //type.AddInterfaceImplementation(typeof(IProxy));
+
+    public void BuildSignalConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF)
+    {
+      Type[] pars = {typeof(Service), typeof(string)};
+      ConstructorBuilder constructor = typeB.DefineConstructor(MethodAttributes.RTSpecialName | 
+                                                              MethodAttributes.Public,
+                                                              CallingConventions.Standard, pars);
+
+      ILGenerator generator = constructor.GetILGenerator();
+      generator.Emit(OpCodes.Ldarg_0);
+      generator.Emit(OpCodes.Call, this.introspector.Constructor);
+      //generator.EmitWriteLine("service = myService");
+      generator.Emit(OpCodes.Ldarg_1);
+      generator.Emit(OpCodes.Stsfld, serviceF);
+      //generator.EmitWriteLine("this.pathName = pathName");
+      generator.Emit(OpCodes.Ldarg_0);
+      generator.Emit(OpCodes.Ldarg_2);
+      generator.Emit(OpCodes.Stfld, pathF);
       
-      FieldBuilder serviceF = typeB.DefineField("service", 
-                                               typeof(Service), 
-                                               FieldAttributes.Private | 
-                                               FieldAttributes.Static);
-      FieldBuilder interfaceF = typeB.DefineField("interfaceName", 
-                                                 typeof(string), 
+      //generator.EmitWriteLine("return");
+      generator.Emit(OpCodes.Ret);
+    }
+    
+    public void BuildFinalizer (TypeBuilder tb, FieldInfo serviceF, FieldInfo deleF)
+    {
+       // Note that this is a *HORRIBLE* example of how to build a finalizer
+       // It doesn't use the try/finally to chain to Object::Finalize. However,
+       // because that is always going to be a nop, lets just ignore that here.
+       // If you are trying to find the right code, look at what mcs does ;-).
+
+       MethodBuilder mb = tb.DefineMethod("Finalize",
+                                         MethodAttributes.Family |
+                                         MethodAttributes.HideBySig |
+                                         MethodAttributes.Virtual, 
+                                         typeof (void), 
+                                         new Type [0]);
+       ILGenerator generator = mb.GetILGenerator();
+
+       //generator.EmitWriteLine("this.service.SignalCalled -= this.delegate_created");
+       generator.Emit (OpCodes.Ldarg_0);
+       generator.Emit (OpCodes.Ldfld, serviceF);
+       generator.Emit (OpCodes.Ldarg_0);
+       generator.Emit (OpCodes.Ldfld, deleF);
+       generator.EmitCall (OpCodes.Callvirt, Service_RemoveSignalCalledMI, null);
+       generator.Emit (OpCodes.Ret);
+    }
+    
+    public object GetSignalProxy()
+    {
+      Type proxyType = Service.ProxyAssembly.GetType(ObjectName + ".SignalProxy");
+
+      if (proxyType == null) {
+       // Build the type
+       TypeBuilder typeB = Service.Module.DefineType(ObjectName + ".SignalProxy", 
+                                                     TypeAttributes.Public, 
+                                                     this.type);
+       
+       FieldBuilder serviceF = typeB.DefineField("service", 
+                                                 typeof(Service), 
                                                  FieldAttributes.Private | 
                                                  FieldAttributes.Static);
-      FieldBuilder pathF = typeB.DefineField("pathName", 
-                                            typeof(string), 
-                                            FieldAttributes.Private);
+       FieldBuilder pathF = typeB.DefineField("pathName", 
+                                              typeof(string), 
+                                              FieldAttributes.Private);
 
-      BuildConstructor(ref typeB, serviceF, interfaceF, pathF);
-
-      // Build the methods
-      foreach (MethodInfo method in this.introspector.Methods) {
-       BuildMethod(method, ref typeB, serviceF, interfaceF, pathF);
-      }
-      
-      Type [] parTypes = new Type[] {typeof(Service), typeof(string), typeof(string)};
-      object [] pars = new object[] {Service, this.introspector.InterfaceName, pathName};
+       BuildSignalConstructor(ref typeB, serviceF, pathF);
+       
+       // Build the signal handlers
+       foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
+         InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
+         foreach (DictionaryEntry signalEntry in interfaceProxy.Signals) {
+           EventInfo eventE = (EventInfo) signalEntry.Value;
+           BuildSignalHandler(eventE, interfaceProxy, ref typeB, serviceF, pathF);
+         }
+       }
+       
+       proxyType = typeB.CreateType();
       
-      Type proxyType = typeB.CreateType();
-
-      // Uncomment the following line to produce a DLL of the
-      // constructed assembly which can then be examined using
-      // monodis. Note that in order for this to work you should copy
-      // the client assembly as a dll file so that monodis can pick it
-      // up.
-      //ProxyAssembly.Save("proxy.dll");
+       // Uncomment the following line to produce a DLL of the
+       // constructed assembly which can then be examined using
+       // monodis. Note that in order for this to work you should copy
+       // the client assembly as a dll file so that monodis can pick it
+       // up.
+       //Service.ProxyAssembly.Save("proxy.dll");
+      }
 
+      Type [] parTypes = new Type[] {typeof(Service), typeof(string)};
+      object [] pars = new object[] {Service, pathName};
+      
       ConstructorInfo constructor = proxyType.GetConstructor(parTypes);
       object instance = constructor.Invoke(pars);
       return instance;
     }
-
-    private ModuleBuilder ServiceModuleBuilder
-    {
-      get
-       {
-         if (Service.module == null) {
-           Service.module = ProxyAssembly.DefineDynamicModule(Service.Name, "proxy.dll", true);
+      
+    
+    public object GetProxy() 
+    { 
+      Type proxyType = Service.ProxyAssembly.GetType(ObjectName + ".Proxy");
+      
+      if (proxyType == null) {
+       // Build the type
+       TypeBuilder typeB = Service.Module.DefineType(ObjectName + ".Proxy", TypeAttributes.Public, this.type);
+       
+       FieldBuilder serviceF = typeB.DefineField("service", 
+                                                 typeof(Service), 
+                                                 FieldAttributes.Private | 
+                                                 FieldAttributes.Static);
+       FieldBuilder pathF = typeB.DefineField("pathName", 
+                                              typeof(string), 
+                                              FieldAttributes.Private);
+       FieldBuilder deleF = typeB.DefineField("delegate_created", 
+                                              typeof(Service.SignalCalledHandler), 
+                                              FieldAttributes.Private);
+       BuildFinalizer (typeB, serviceF, deleF);
+       
+       MethodInfo signalCalledMI = BuildSignalCalled(ref typeB, serviceF, pathF);
+       BuildConstructor(ref typeB, serviceF, pathF, signalCalledMI, deleF);
+       
+       // Build the methods
+       foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
+         InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
+         foreach (DictionaryEntry methodEntry in interfaceProxy.Methods) {
+           MethodInfo method = (MethodInfo) methodEntry.Value;
+           BuildMethod(method, interfaceProxy, ref typeB, serviceF, pathF);
          }
-         
-         return Service.module;
-       }
-    }
-  
-  private Service Service
-    {
-      get
-       {
-         return this.service;
        }
-    }
+       
+       proxyType = typeB.CreateType();
+      
+       // Uncomment the following line to produce a DLL of the
+       // constructed assembly which can then be examined using
+       // monodis. Note that in order for this to work you should copy
+       // the client assembly as a dll file so that monodis can pick it
+       // up.
+       //Service.ProxyAssembly.Save(Service.Name + ".proxy.dll");
+      }
 
-    private string ProxyName
+      Type [] parTypes = new Type[] {typeof(Service), typeof(string)};
+      object [] pars = new object[] {Service, pathName};
+      
+      ConstructorInfo constructor = proxyType.GetConstructor(parTypes);
+      object instance = constructor.Invoke(pars);
+      return instance;
+    }
+    
+    private Service Service
     {
-      get
-       {
-         return this.introspector.InterfaceName + ".Proxy";
-       }
+      get {
+       return this.service;
+      }
     }
 
-    private AssemblyBuilder ProxyAssembly
+    private string ObjectName
     {
-      get
-       {
-         if (this.proxyAssembly == null){
-           AssemblyName assemblyName = new AssemblyName();
-           assemblyName.Name = "DBusProxy";
-           this.proxyAssembly = Thread.GetDomain().DefineDynamicAssembly(assemblyName, 
-                                                                         AssemblyBuilderAccess.RunAndSave);
-         }
-         
-         return this.proxyAssembly;
-       }
+      get {
+       return this.introspector.ToString();
+      }
     }
   }
 }