public static TResult CastProxy <TResult>(object proxy) where TResult : class { var realProxy = TinyProtocol.GetRealProxy(proxy); return(realProxy?.CastProxy <TResult>().Result); }
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)); }
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)); }
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)); }
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)); }
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()); }
public static void RegisterCustomProxyFactory <TProxyFactory>() where TProxyFactory : class { TinyProtocol.RegisterCustomProxyFactory <TProxyFactory>(); }
/// <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()); }
public static Task KeepAlive(object proxy) { return(TinyProtocol.GetRealProxy(proxy).KeepAlive()); }
public static string GetExternalAddress(object proxy) { return(TinyProtocol.GetRealProxy(proxy)?.Address.Encode()); }
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>(); }
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()); }