static void GenerateEndMethodImpl(CodeClass c, MethodInfo endProcessMethod, string name, MethodInfo mi) { CodeMethod m = c.ImplementMethod(mi); CodeBuilder b = m.CodeBuilder; ParameterInfo [] pinfos = mi.GetParameters(); ParameterInfo p = pinfos [0]; CodeArgumentReference asyncResultRef = m.GetArg(0); CodeVariableDeclaration paramsDecl = new CodeVariableDeclaration(typeof(object []), "parameters"); b.CurrentBlock.Add(paramsDecl); CodeVariableReference paramsRef = paramsDecl.Variable; b.Assign(paramsRef, new CodeNewArray(typeof(object), new CodeLiteral(pinfos.Length - 1))); /* * for (int i = 0; i < pinfos.Length - 2; i++) { * ParameterInfo par = pinfos [i]; * if (!par.IsOut) * b.Assign ( * new CodeArrayItem (paramsRef, new CodeLiteral (i)), * new CodeCast (typeof (object), * new CodeArgumentReference (par.ParameterType, par.Position + 1, "arg" + i))); * } */ #if USE_OD_REFERENCE_IN_PROXY CodePropertyReference argMethodInfo = GetOperationMethod(m, b, name, "EndMethod"); #else CodeMethodCall argMethodInfo = new CodeMethodCall(typeof(MethodBase), "GetCurrentMethod"); #endif CodeLiteral argOperName = new CodeLiteral(name); CodeVariableReference retValue = null; if (mi.ReturnType == typeof(void)) { b.Call(m.GetThis(), endProcessMethod, argMethodInfo, argOperName, paramsRef, asyncResultRef); } else { CodeVariableDeclaration retValueDecl = new CodeVariableDeclaration(mi.ReturnType, "retValue"); b.CurrentBlock.Add(retValueDecl); retValue = retValueDecl.Variable; b.Assign(retValue, new CodeCast(mi.ReturnType, b.CallFunc(m.GetThis(), endProcessMethod, argMethodInfo, argOperName, paramsRef, asyncResultRef))); } // FIXME: fill out parameters if (retValue != null) { b.Return(retValue); } }
static void GenerateBeginMethodImpl(CodeClass c, MethodInfo beginProcessMethod, string name, MethodInfo mi) { CodeMethod m = c.ImplementMethod(mi); CodeBuilder b = m.CodeBuilder; // object [] parameters = new object [x]; // parameters [0] = arg1; // parameters [1] = arg2; // ... // (return) BeginProcess (Contract.Operations [operName].BeginMethod, operName, parameters, asyncCallback, userState); ParameterInfo [] pinfos = mi.GetParameters(); CodeVariableDeclaration paramsDecl = new CodeVariableDeclaration(typeof(object []), "parameters"); b.CurrentBlock.Add(paramsDecl); CodeVariableReference paramsRef = paramsDecl.Variable; b.Assign(paramsRef, new CodeNewArray(typeof(object), new CodeLiteral(pinfos.Length - 2))); for (int i = 0; i < pinfos.Length - 2; i++) { ParameterInfo par = pinfos [i]; if (!par.IsOut) { b.Assign( new CodeArrayItem(paramsRef, new CodeLiteral(i)), new CodeCast(typeof(object), m.GetArg(i))); } } #if USE_OD_REFERENCE_IN_PROXY CodePropertyReference argMethodInfo = GetOperationMethod(m, b, name, "BeginMethod"); #else CodeMethodCall argMethodInfo = new CodeMethodCall(typeof(MethodBase), "GetCurrentMethod"); #endif CodeLiteral argOperName = new CodeLiteral(name); ParameterInfo p = pinfos [pinfos.Length - 2]; CodeArgumentReference callbackRef = new CodeArgumentReference(typeof(AsyncCallback), p.Position + 1, p.Name); p = pinfos [pinfos.Length - 1]; CodeArgumentReference stateRef = new CodeArgumentReference(typeof(object), p.Position + 1, p.Name); CodeVariableDeclaration retValueDecl = new CodeVariableDeclaration(mi.ReturnType, "retValue"); b.CurrentBlock.Add(retValueDecl); CodeVariableReference retValue = retValueDecl.Variable; b.Assign(retValue, new CodeCast(mi.ReturnType, b.CallFunc(m.GetThis(), beginProcessMethod, argMethodInfo, argOperName, paramsRef, callbackRef, stateRef))); b.Return(retValue); }
static CodePropertyReference GetOperationMethod(CodeMethod m, CodeBuilder b, string name, string methodPropertyName) { return(new CodePropertyReference( b.CallFunc( // this.Contract.Operations new CodePropertyReference( new CodePropertyReference( m.GetThis(), typeof(ClientRuntimeChannel).GetProperty("Contract")), typeof(ContractDescription).GetProperty("Operations")), // .Find (name) typeof(OperationDescriptionCollection).GetMethod("Find"), new CodeLiteral(name)), // .SyncMethod typeof(OperationDescription).GetProperty(methodPropertyName))); }
public static Type CreateCallbackProxyType(DispatchRuntime dispatchRuntime, Type callbackType) { var ed = dispatchRuntime.EndpointDispatcher; var channelDispatcher = ed.ChannelDispatcher; Type contractType = channelDispatcher != null?channelDispatcher.Host.ImplementedContracts.Values.First(hcd => hcd.Name == ed.ContractName && hcd.Namespace == ed.ContractNamespace).ContractType : dispatchRuntime.Type; var cd = ContractDescriptionGenerator.GetCallbackContract(contractType, callbackType); string modname = "dummy"; Type crtype = typeof(DuplexServiceRuntimeChannel); // public class __clientproxy_MyContract : ClientRuntimeChannel, [ContractType] CodeClass c = new CodeModule(modname).CreateClass( "__callbackproxy_" + cd.Name, crtype, new Type [] { callbackType }); // // public __callbackproxy_MyContract ( // IChannel channel, DispatchRuntime runtime) // : base (channel, runtime) // { // } // Type [] ctorargs = new Type [] { typeof(IChannel), typeof(DispatchRuntime) }; CodeMethod ctor = c.CreateConstructor( MethodAttributes.Public, ctorargs); CodeBuilder b = ctor.CodeBuilder; MethodBase baseCtor = crtype.GetConstructors( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) [0]; if (baseCtor == null) { throw new Exception("INTERNAL ERROR: DuplexServiceRuntimeChannel.ctor() was not found."); } b.Call( ctor.GetThis(), baseCtor, new CodeArgumentReference(typeof(IChannel), 1, "arg0"), new CodeArgumentReference(typeof(DispatchRuntime), 2, "arg1")); return(CreateProxyTypeOperations(crtype, c, cd)); }
public static Type CreateProxyType(Type contractInterface, ContractDescription cd, bool duplex) { string modname = "dummy"; Type crtype = #if !NET_2_1 duplex ? typeof(DuplexClientRuntimeChannel) : #endif typeof(ClientRuntimeChannel); // public class __clientproxy_MyContract : ClientRuntimeChannel, [ContractType] CodeClass c = new CodeModule(modname).CreateClass( "__clientproxy_" + cd.Name, crtype, new Type [] { contractInterface }); // // public __clientproxy_MyContract ( // ServiceEndpoint arg1, ChannelFactory arg2, EndpointAddress arg3, Uri arg4) // : base (arg1, arg2, arg3, arg4) // { // } // Type [] ctorargs = new Type [] { typeof(ServiceEndpoint), typeof(ChannelFactory), typeof(EndpointAddress), typeof(Uri) }; CodeMethod ctor = c.CreateConstructor( MethodAttributes.Public, ctorargs); CodeBuilder b = ctor.CodeBuilder; MethodBase baseCtor = crtype.GetConstructors( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) [0]; if (baseCtor == null) { throw new Exception("INTERNAL ERROR: ClientRuntimeChannel.ctor() was not found."); } b.Call( ctor.GetThis(), baseCtor, new CodeArgumentReference(typeof(ServiceEndpoint), 1, "arg0"), new CodeArgumentReference(typeof(ChannelFactory), 2, "arg1"), new CodeArgumentReference(typeof(EndpointAddress), 3, "arg2"), new CodeArgumentReference(typeof(Uri), 4, "arg3")); return(CreateProxyTypeOperations(crtype, c, cd)); }
public static Type CreateProxyType(Type requestedType, ContractDescription cd, bool duplex) { ClientProxyKey key = new ClientProxyKey(requestedType, cd, duplex); Type res; lock (proxy_cache) { if (proxy_cache.TryGetValue(key, out res)) { return(res); } } string modname = "dummy"; Type crtype = #if !NET_2_1 duplex ? typeof(DuplexClientRuntimeChannel) : #endif typeof(ClientRuntimeChannel); // public class __clientproxy_MyContract : (Duplex)ClientRuntimeChannel, [ContractType] var types = new List <Type> (); types.Add(requestedType); if (!cd.ContractType.IsAssignableFrom(requestedType)) { types.Add(cd.ContractType); } if (cd.CallbackContractType != null && !cd.CallbackContractType.IsAssignableFrom(requestedType)) { types.Add(cd.CallbackContractType); } CodeClass c = new CodeModule(modname).CreateClass("__clientproxy_" + cd.Name, crtype, types.ToArray()); // // public __clientproxy_MyContract ( // ServiceEndpoint arg1, ChannelFactory arg2, EndpointAddress arg3, Uri arg4) // : base (arg1, arg2, arg3, arg4) // { // } // Type [] ctorargs = new Type [] { typeof(ServiceEndpoint), typeof(ChannelFactory), typeof(EndpointAddress), typeof(Uri) }; CodeMethod ctor = c.CreateConstructor( MethodAttributes.Public, ctorargs); CodeBuilder b = ctor.CodeBuilder; MethodBase baseCtor = crtype.GetConstructors( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) [0]; if (baseCtor == null) { throw new Exception("INTERNAL ERROR: ClientRuntimeChannel.ctor() was not found."); } b.Call( ctor.GetThis(), baseCtor, new CodeArgumentReference(typeof(ServiceEndpoint), 1, "arg0"), new CodeArgumentReference(typeof(ChannelFactory), 2, "arg1"), new CodeArgumentReference(typeof(EndpointAddress), 3, "arg2"), new CodeArgumentReference(typeof(Uri), 4, "arg3")); res = CreateProxyTypeOperations(crtype, c, cd); lock (proxy_cache) { proxy_cache [key] = res; } return(res); }
static void GenerateMethodImpl(CodeClass c, MethodInfo processMethod, string name, MethodInfo mi) { CodeMethod m = c.ImplementMethod(mi); CodeBuilder b = m.CodeBuilder; // object [] parameters = new object [x]; // parameters [0] = arg1; // parameters [1] = arg2; // ... // (return) Process (Contract.Operations [operName].SyncMethod, operName, parameters); ParameterInfo [] pinfos = mi.GetParameters(); CodeVariableDeclaration paramsDecl = new CodeVariableDeclaration(typeof(object []), "parameters"); b.CurrentBlock.Add(paramsDecl); CodeVariableReference paramsRef = paramsDecl.Variable; b.Assign(paramsRef, new CodeNewArray(typeof(object), new CodeLiteral(pinfos.Length))); for (int i = 0; i < pinfos.Length; i++) { ParameterInfo par = pinfos [i]; if (!par.IsOut) { b.Assign( new CodeArrayItem(paramsRef, new CodeLiteral(i)), new CodeCast(typeof(object), new CodeArgumentReference(par.ParameterType, par.Position + 1, "arg" + i))); } } #if USE_OD_REFERENCE_IN_PROXY CodePropertyReference argMethodInfo = GetOperationMethod(m, b, name, "SyncMethod"); #else CodeMethodCall argMethodInfo = new CodeMethodCall(typeof(MethodBase), "GetCurrentMethod"); #endif CodeLiteral argOperName = new CodeLiteral(name); CodeVariableReference retValue = null; if (mi.ReturnType == typeof(void)) { b.Call(m.GetThis(), processMethod, argMethodInfo, argOperName, paramsRef); } else { CodeVariableDeclaration retValueDecl = new CodeVariableDeclaration(mi.ReturnType, "retValue"); b.CurrentBlock.Add(retValueDecl); retValue = retValueDecl.Variable; b.Assign(retValue, new CodeCast(mi.ReturnType, b.CallFunc(m.GetThis(), processMethod, argMethodInfo, argOperName, paramsRef))); } for (int i = 0; i < pinfos.Length; i++) { ParameterInfo par = pinfos [i]; if (par.IsOut || par.ParameterType.IsByRef) { b.Assign( new CodeArgumentReference(par.ParameterType, par.Position + 1, "arg" + i), new CodeCast(par.ParameterType.GetElementType(), new CodeArrayItem(paramsRef, new CodeLiteral(i)))); } } if (retValue != null) { b.Return(retValue); } }