private byte[] CallToData(MethodInfo method, IInvocation invocation)
        {
            using (var mem = new MemoryStream())
            {
                var call = new MarshallingMessage
                {
                    Interface  = method.DeclaringType.Name,
                    Method     = method.Name,
                    ParamCount = invocation.Arguments.Length
                };
                for (int i = 0; i < invocation.Arguments.Length; i++)
                {
                    if (invocation.Arguments[i] == null)
                    {
                        call.NullParamIndices.Add(i);
                    }
                }
                ProtoSerializer.Serialize(mem, call);

                foreach (var arg in invocation.Arguments)
                {
                    if (arg != null)
                    {
                        ProtoSerializer.Serialize(mem, arg);
                    }
                }

                return(mem.ToArray());
            }
        }
 private object DataToResult(byte[] data, MethodInfo method)
 {
     if (data.Length == 0)
     {
         return(Convert.ChangeType(null, method.ReturnType));
     }
     using (var mem = new MemoryStream(data))
     {
         var result = ProtoSerializer.Deserialize(mem, method.ReturnType);
         return(Convert.ChangeType(result, method.ReturnType));
     }
 }
 private byte[] ResultToBytes(object result)
 {
     if (result == null)
     {
         return(new byte[0]);
     }
     using (var mem = new MemoryStream())
     {
         ProtoSerializer.Serialize(mem, result);
         return(mem.ToArray());
     }
 }
        public byte[] Call(byte[] data)
        {
            using (var mem = new MemoryStream(data))
            {
                var msg        = ProtoSerializer.Deserialize <MarshallingMessage>(mem);
                var obj        = GetImplementation(msg.Interface);
                var method     = obj.GetType().GetMethod(msg.Method);
                var parameters = method.GetParameters();

                if (parameters.Count() != msg.ParamCount && parameters.Count(p => p.IsOptional == false) != msg.ParamCount)
                {
                    throw new InvalidDataException(
                              $"Method {msg.Interface}.{msg.Method} received {msg.ParamCount} parameters, but {parameters.Length} required");
                }
                var values = new object[parameters.Count()];
                for (var i = 0; i < parameters.Count(); i++)
                {
                    if (msg.NullParamIndices.Contains(i))
                    {
                        continue;
                    }
                    values[i] = ProtoSerializer.Deserialize(mem, parameters[i].ParameterType);
                    if (parameters[i].IsOptional && values[i] == null)
                    {
                        values[i] = Type.Missing;
                    }
                }

                try
                {
                    var result = method.Invoke(obj, values);
                    return(ResultToBytes(result));
                }
                catch (Exception e)
                {
                    if (e is TargetInvocationException && e.InnerException != null)
                    {
                        throw e.InnerException;
                    }
                    throw;
                }
            }
        }