Ejemplo n.º 1
0
        public static TResult CastProxy <TResult>(object proxy)
            where TResult : class
        {
            var realProxy = TinyProtocol.GetRealProxy(proxy);

            return(realProxy?.CastProxy <TResult>().Result);
        }
Ejemplo n.º 2
0
 public void SetUp()
 {
     TinyProtocol.RegisterCustomProxyFactory <CustomProxyFactory>();
     _executor = new Mock <IExecutor>();
     _endpoint = new Mock <IEndpoint>();
     _endpoint.Setup(x => x.GetExecutor(It.IsAny <string>(), It.IsAny <TimeSpan?>())).Returns <string, TimeSpan?>((x, t) => new PrefixedExecutor(x, _executor.Object));
 }
Ejemplo n.º 3
0
        private static void ImplementGetter(TypeBuilder typeBuilder, ExpressionPropertyBuilder builder, PropertyInfo property)
        {
            if (TinyProtocol.Check(property.PropertyType).CanBuildProxy())
            {
                var field = typeBuilder.DefineField("<prx>_" + property.Name, property.PropertyType, FieldAttributes.Private);
                builder.ImplementGetter(
                    Expression.Coalesce(
                        builder.This.MemberField(field),
                        Expression.Assign(
                            builder.This.MemberField(field),
                            builder.This.CallMember(CreateMemberProxy.MakeGenericMethod(property.PropertyType), Expression.Constant(property.Name)))));
                return;
            }

            bool isSerializable = TinyProtocol.Check(property.PropertyType).CanDeserialize();
            var  dict           = Expression.Parameter(typeof(IDictionary <string, string>));
            var  block          = new List <Expression>();

            block.Add(Expression.Assign(dict, builder.This.CallMember(CreateQuery)));
            if (isSerializable)
            {
                block.Add(Wait(builder.This.CallMember(ExecuteQueryRet.MakeGenericMethod(property.PropertyType), Expression.Constant(property.Name), dict)));
            }
            else
            {
                block.Add(Expression.Throw(Expression.New(typeof(Exception).GetConstructor(new [] { typeof(string) }), Expression.Constant("incompatible return type"))));
                block.Add(Expression.Default(property.PropertyType));
            }

            builder.ImplementGetter(
                Expression.Block(
                    property.PropertyType,
                    new[] { dict },
                    block));
        }
            private Expression DeserializeParameter(Expression parameter, Expression endpoint, Type parameterType)
            {
                if (TinyProtocol.Check(parameterType).CanDeserialize())
                {
                    return(parameter.Deserialize(endpoint, parameterType));
                }

                throw new InvalidOperationException(string.Format("Unsupported parameter type '{0}'", parameterType));
            }
Ejemplo n.º 5
0
 public static void InitDefaultEndpoint(
     TimeSpan?executionTimeout = null,
     TimeSpan?cleanupInterval  = null,
     int callbackPort          = TinyProtocol.DefaultCallbackPort)
 {
     _defaultClientEndpoint = new Endpoint(
         TinyProtocol.CreatePrefix(null, TinyProtocol.DefaultCallbackPort, Guid.NewGuid().ToString("N")),
         null,
         false,
         cleanupInterval ?? TimeSpan.Zero,
         executionTimeout ?? TimeSpan.FromSeconds(30));
 }
Ejemplo n.º 6
0
            public Task <T> ConnectAsync(TimeSpan?timeout = null)
            {
                var actualConnectTimeout = timeout ?? TimeSpan.FromSeconds(1);

                var address = new ObjectAddress(TinyProtocol.CreatePrefix(_hostname, _port, _name), null).Encode();

                var executor = DefaultClientEndpoint.GetExecutor(address, actualConnectTimeout);

                return(executor.Execute(TinyProtocol.MetadataPath).ContinueWith(meta =>
                {
                    // use result to correctly rethrow task exceptions, no actual checking yet
                    CheckMeta(meta.Result);

                    return TinyProtocol.Serializer <T> .Deserialize(DefaultClientEndpoint, address);
                }, TaskContinuationOptions.ExecuteSynchronously));
            }
Ejemplo n.º 7
0
        private static void ImplementSetter(ExpressionPropertyBuilder builder, PropertyInfo property)
        {
            var dict  = Expression.Parameter(typeof(IDictionary <string, string>));
            var block = new List <Expression>();

            block.Add(Expression.Assign(dict, builder.This.CallMember(CreateQuery)));
            block.Add(dict.CallMember(AddParameter, Expression.Constant("value"), builder.Value.Serialize(builder.This.MemberField(typeof(ProxyBase).GetField("Endpoint", BindingFlags.Instance | BindingFlags.NonPublic)))));
            if (TinyProtocol.Check(property.PropertyType).CanSerialize())
            {
                block.Add(Wait(builder.This.CallMember(ExecuteQuery, Expression.Constant(property.Name), dict)));
            }
            else
            {
                block.Add(Expression.Throw(Expression.New(typeof(Exception).GetConstructor(new[] { typeof(string) }), Expression.Constant("incompatible return type"))));
                block.Add(Expression.Default(property.PropertyType));
            }

            builder.ImplementSetter(
                Expression.Block(
                    typeof(void),
                    new[] { dict },
                    block));
        }
            private Func <T, IEndpoint, IDictionary <string, string>, Task <string> > BindAction(string path)
            {
                var target     = Expression.Parameter(typeof(T));
                var endpoint   = Expression.Parameter(typeof(IEndpoint));
                var parameters = Expression.Parameter(typeof(IDictionary <string, string>));

                Expression current = target;
                var        entries = path.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);

                for (int i = 0; i < entries.Length; ++i)
                {
                    var property = current.Type.GetTypeHierarchy().Select(x => x.GetProperty(entries[i], BindingFlags.Public | BindingFlags.Instance)).FirstOrDefault(x => x != null);
                    if (property != null)
                    {
                        current = Expression.Property(current, property);
                        continue;
                    }

                    if (i != entries.Length - 1)
                    {
                        current = ThrowExpression(string.Format("member '{0}' not found", entries[i]));
                        break;
                    }

                    if (entries[i] == TinyProtocol.DetachCommand)
                    {
                        break;
                    }

                    var indexer = typeof(IDictionary <string, string>).GetProperty("Item");
                    var method  = current.Type.GetTypeHierarchy()
                                  .SelectMany(x => x.GetMethods(BindingFlags.Public | BindingFlags.Instance))
                                  .Where(x => !x.IsGenericMethod)
                                  .FirstOrDefault(x => x.Name == entries[i] && x.GetParameters().All(p => TinyProtocol.Check(p.ParameterType).CanDeserialize()));
                    if (method == null)
                    {
                        current = ThrowExpression(string.Format("member '{0}' not found", entries[i]));
                        break;
                    }

                    current = Expression.Call(
                        current,
                        method,
                        method.GetParameters().Select(x => DeserializeParameter(Expression.Property(parameters, indexer, Expression.Constant(x.Name)), endpoint, x.ParameterType)).ToArray());
                }

                var signature = new AsyncTypeSignature(current.Type);

                if (TinyProtocol.Check(signature.ReturnType).CanSerialize())
                {
                    if (signature.ReturnType == typeof(void))
                    {
                        if (signature.IsAsync)
                        {
                            current = Expression.Call(typeof(DispatcherHelpers).GetMethod("WrapTask"), current);
                        }
                        else
                        {
                            current = Expression.Block(current, Expression.Call(typeof(Task).GetMethod("FromResult").MakeGenericMethod(typeof(string)), Expression.Constant(string.Empty)));
                        }
                    }
                    else
                    {
                        current = Expression.Call(typeof(DispatcherHelpers).GetMethod(signature.IsAsync ? "WrapValueAsync" : "WrapValue").MakeGenericMethod(signature.ReturnType), endpoint, current);
                    }
                }
                else
                {
                    throw new Exception("cannot invoke method - unsupported return type");
                }

                return(Expression.Lambda <Func <T, IEndpoint, IDictionary <string, string>, Task <string> > >(
                           current,
                           target,
                           endpoint,
                           parameters).Compile());
            }
Ejemplo n.º 9
0
 public static void RegisterCustomProxyFactory <TProxyFactory>()
     where TProxyFactory : class
 {
     TinyProtocol.RegisterCustomProxyFactory <TProxyFactory>();
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Unitialized dispatcher for given proxy. If root proxy is supplied, all nested dispatchers are uninitialized instead.
 /// </summary>
 /// <param name="proxy">proxy object to uninitialize</param>
 /// <returns></returns>
 public static Task Dispose(object proxy)
 {
     return(TinyProtocol.GetRealProxy(proxy).DisposeRemote());
 }
Ejemplo n.º 11
0
 public static Task KeepAlive(object proxy)
 {
     return(TinyProtocol.GetRealProxy(proxy).KeepAlive());
 }
Ejemplo n.º 12
0
 public static string GetExternalAddress(object proxy)
 {
     return(TinyProtocol.GetRealProxy(proxy)?.Address.Encode());
 }
Ejemplo n.º 13
0
            public IDisposable AtEndpoint(string endpointName)
            {
                var prefix = TinyProtocol.CreatePrefix(_allowExternalConnections ? "*" : null, _port, endpointName);

                return(new Endpoint(prefix, _service, _useThreadDispatcher, _cleanupInterval, _executionTimeout));
            }
 public void Setup()
 {
     _endpoint = new Mock <IEndpoint>();
     TinyProtocol.RegisterCustomProxyFactory <CustomProxyFactory>();
 }
Ejemplo n.º 15
0
        public static Type BuildProxyType(Type interfaceType)
        {
            var typeBuilder = ProxiesModule.DefineType(interfaceType.Name + "_Proxy" + _counter++, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed, typeof(ProxyBase), new[] { interfaceType });
            var constructorParameterTypes = new[] { typeof(IEndpoint), typeof(string) };
            var baseConstructor           = typeof(ProxyBase).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, constructorParameterTypes, null);

            var constructorBuilder     = typeBuilder.DefineExpressionConstructor(baseConstructor);
            var constructorExpressions = new List <Expression>();

            foreach (var method in interfaceType.GetPublicMethods())
            {
                if (method.IsSpecialName || !method.IsVirtual)
                {
                    continue;
                }

                if (method.IsGenericMethod)
                {
                    var parameters     = method.GetParameters();
                    var parameterTypes = parameters.Select(x => x.ParameterType).ToArray();
                    var methodBuilder  = typeBuilder.DefineMethod(method.Name, method.Attributes & ~MethodAttributes.Abstract, method.CallingConvention, method.ReturnType, parameterTypes);
                    methodBuilder.DefineGenericParameters(method.GetGenericArguments().Select(x => x.Name).ToArray());
                    var il = methodBuilder.GetILGenerator();
                    il.Emit(OpCodes.Ldstr, "cannot invoke generic method");
                    il.Emit(OpCodes.Newobj, ExceptionConstructor);
                    il.Emit(OpCodes.Throw);
                    if (method.ReturnType != typeof(void))
                    {
                        il.Emit(OpCodes.Ldloc, il.DeclareLocal(method.ReturnType));
                    }
                    il.Emit(OpCodes.Ret);

                    continue;
                }

                var signature = new AsyncTypeSignature(method.ReturnType);
                var builder   = typeBuilder.DefineExpressionMethod(method);

                var dict  = Expression.Parameter(typeof(IDictionary <string, string>));
                var block = new List <Expression>();
                block.Add(Expression.Assign(dict, builder.This.CallMember(CreateQuery)));

                string errorMessage = null;
                if (builder.Parameters.All(x => TinyProtocol.Check(x.Type).CanSerialize()))
                {
                    block.AddRange(builder.Parameters.Select(x => dict.CallMember(
                                                                 AddParameter,
                                                                 Expression.Constant(x.Name),
                                                                 x.Serialize(builder.This.MemberField(typeof(ProxyBase).GetField("Endpoint", BindingFlags.Instance | BindingFlags.NonPublic))))));

                    if (TinyProtocol.Check(signature.ReturnType).CanDeserialize())
                    {
                        Expression call;
                        call = signature.ReturnType == typeof(void)
                            ? builder.This.CallMember(ExecuteQuery, Expression.Constant(method.Name), dict)
                            : builder.This.CallMember(ExecuteQueryRet.MakeGenericMethod(signature.ReturnType), Expression.Constant(method.Name), dict);

                        block.Add(signature.IsAsync ? call : Wait(call));
                    }
                    else
                    {
                        errorMessage = string.Format("incompatible return type '{0}'", signature.ReturnType);
                    }
                }
                else
                {
                    errorMessage = "cannot serialize all parameter types";
                }

                if (errorMessage != null)
                {
                    block.Add(Expression.Throw(Expression.New(ExceptionConstructor, Expression.Constant(errorMessage))));
                    block.Add(Expression.Default(method.ReturnType));
                }

                builder.Implement(Expression.Block(
                                      method.ReturnType,
                                      new[] { dict },
                                      block));
            }

            foreach (var property in interfaceType.GetPublicProperies())
            {
                var builder = typeBuilder.DefineExpressionProperty(property);
                if (property.CanRead)
                {
                    ImplementGetter(typeBuilder, builder, property);
                }

                if (property.CanWrite)
                {
                    ImplementSetter(builder, property);
                }
            }

            constructorExpressions.Add(Expression.Empty());
            constructorBuilder.Implement(Expression.Block(typeof(void), constructorExpressions));
            return(typeBuilder.CreateType());
        }