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));
        }
Exemple #5
0
        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);
            }
        }