/// <summary> /// Register remotable object without registering it's config. /// </summary> /// <param name="remotable"></param> /// <param name="remoteId"></param> /// <param name="subRemote"></param> /// <param name="own"></param> /// <returns></returns> public DextopConfig TrackRemotableComponent(IDextopRemotable remotable, String remoteId = null, bool subRemote = true, bool own = true) { if (own) { TrackDisposable(remotable); } return(Register(remotable, remoteId, subRemote)); }
/// <summary> /// Adds the remotable component. Remotable component configuration will be available on the client side. /// </summary> /// <param name="name">The name.</param> /// <param name="remotable">The remotable.</param> /// <param name="remoteId">The remote id.</param> /// <param name="subRemote">if set to <c>true</c> [sub remote].</param> /// <param name="own">if set to <c>true</c> [own].</param> public void AddRemotableComponent(String name, IDextopRemotable remotable, String remoteId = null, bool subRemote = true, bool own = true) { if (componentsConfig == null) { componentsConfig = new DextopConfig(); } componentsConfig.Add(name, TrackRemotableComponent(remotable, remoteId, subRemote, own)); }
public DextopRemoteMethodInvokeResult Invoke(IDextopRemotable target, string methodName, string[] arguments, DextopFormSubmit form) { if (methodName == "Instantiate" && arguments.Length>0) return Instantiate(target, arguments); if (methodName == "Dispose") { try { target.Dispose(); return new DextopRemoteMethodInvokeResult { Success = true }; } catch (Exception ex) { return new DextopRemoteMethodInvokeResult { Success = false, Exception = ex }; } } try { var type = target.GetType(); var method = GetMethod(type, methodName); ++method.InvokeCount; int offset = form == null ? 0 : 1; object[] args = new object[method.Args.Length]; if (form != null) args[0] = form; if (arguments.Length + offset != method.Args.Length) throw new DextopException("Invalid number of arguments for a remote method call."); for (var i = 0; i < arguments.Length; i++) args[i + offset] = DextopUtil.DecodeValue(arguments[i], method.Args[i + offset]); var result = method.MethodInfo.Invoke(target, args); return new DextopRemoteMethodInvokeResult { Success = true, Result = result }; } catch (TargetInvocationException tix) { return new DextopRemoteMethodInvokeResult { Success = false, Exception = tix.InnerException ?? tix }; } catch (Exception ex) { return new DextopRemoteMethodInvokeResult { Success = false, Exception = ex }; } }
internal DextopConfig Register(DextopRemote parent, IDextopRemotable remotable, String remoteId = null, bool subRemote = true) { if (remotable == null) throw new ArgumentNullException("remotable"); bool isClientInitiated; if (remoteId == null) { remoteId = Interlocked.Increment(ref nextRemoteId).ToString(); isClientInitiated = parent!=null && parent.IsClientInitiated; } else if (subRemote) { if (parent == null) throw new DextopInternalException(); remoteId = parent.RemoteId + '.' + remoteId; isClientInitiated = parent.IsClientInitiated; } else isClientInitiated = true; var context = new RemotableContext { Remotable = remotable }; var remote = new DextopRemote(Context, remoteId, isClientInitiated); var clientTypeName = DextopApplication.MapTypeName(remotable.GetType()); try { var config = new DextopConfig(); remotable.InitRemotable(remote, config); if (!remote.IsClientInitiated) { DextopConfig remoteProxyConfig; var remoteTypeName = remote.RemoteHostType ?? clientTypeName; if (remoteTypeName != null) { config.Add("alias", remoteTypeName); remoteProxyConfig = new DextopConfig(); config.Add("remote", remoteProxyConfig); } else { remoteProxyConfig = config; } remoteProxyConfig.Add("remoteId", remoteId); remoteProxyConfig.Add("alias", DextopUtil.GetRemotingProxyTypeName(clientTypeName)); if (remote.componentsConfig != null) { remoteProxyConfig.Add("components", remote.componentsConfig); //config not needed anymore - free memory remote.componentsConfig = null; } } if (!remotables.TryAdd(remoteId, context)) throw new DextopInternalException(); return config; } catch { remote.Dispose(); remotable.Dispose(); throw; } }
DextopRemoteMethodInvokeResult Instantiate(IDextopRemotable target, String[] arguments) { try { if (arguments.Length < 1) { throw new InvalidDextopRemoteMethodCallException(); } InstantiateOptions options; if (arguments[0] != null && arguments[0].StartsWith("{")) { options = DextopUtil.Decode <InstantiateOptions>(arguments[0]); } else { options = new InstantiateOptions { subRemote = true, type = arguments[0] } }; if (options.type == null) { throw new InvalidDextopRemoteMethodCallException(); } String config = null; if (arguments.Length > 1) { config = arguments[1]; } if (options.type == null) { throw new InvalidDextopRemoteMethodCallException(); } List <RemotableConstructor> constructors; if (!constructorCache.TryGetValue(options.type, out constructors)) { String typeName; DextopConfig routeParams; if (MatchRoutes(options.type, out typeName, out routeParams)) { return(Instantiate(target, new[] { typeName, DextopUtil.Encode(routeParams) })); } if (constructors == null || constructors.Count == 0) { constructors = LoadRemotableConstructors(options.type); } } if (constructors == null || constructors.Count == 0) { throw new InvalidDextopRemoteMethodCallException(); } object[] args; RemotableConstructor c; if (config == null) { args = new object[0]; c = constructors.FirstOrDefault(a => a.ArgumentsType == ConstructorArgments.Default); if (c == null) { c = constructors.FirstOrDefault(a => a.ArgumentsType == ConstructorArgments.Hash); args = new object[1]; } } else if (config.StartsWith("[")) { var argss = DextopUtil.Decode <String[]>(config); c = constructors.Where(a => a.ArgumentsType == ConstructorArgments.Array && a.Args.Length >= argss.Length).OrderBy(a => a.Args.Length).FirstOrDefault(); if (c == null) { c = constructors.Where(a => a.ArgumentsType == ConstructorArgments.Array).OrderByDescending(a => a.Args.Length).FirstOrDefault(); } if (c == null) { c = constructors.FirstOrDefault(a => a.ArgumentsType == ConstructorArgments.Hash); } if (c == null) { c = constructors.FirstOrDefault(a => a.ArgumentsType == ConstructorArgments.Default); } if (c == null) { throw new InvalidDextopRemoteMethodCallException(); } args = new object[c.Args.Length]; for (var i = 0; i < c.Args.Length && i < argss.Length; i++) { args[i] = DextopUtil.DecodeValue(argss[i], c.Args[i].ParameterType); } } else if (config.StartsWith("{")) { c = constructors.FirstOrDefault(a => a.ArgumentsType == ConstructorArgments.Hash); if (c != null) { args = new object[1] { DextopUtil.Decode(config, c.Args[0].ParameterType) }; } else { var configs = DextopUtil.Decode <Dictionary <String, String> >(config) ?? new Dictionary <String, String>(); var candidates = constructors.Select(a => new { Constructor = a, ArgumentMatch = a.Args.Count(b => configs.ContainsKey(b.Name)) }).OrderByDescending(x => x.ArgumentMatch).ToArray(); c = null; foreach (var cand in candidates) { if (cand.ArgumentMatch == configs.Count && cand.Constructor.Args.Length == cand.ArgumentMatch) { c = cand.Constructor; break; } } if (c == null) // if we still don't have a match take the candidate with the biggest number of matching arguments, and prefer parameterless constructor if zero { c = candidates.OrderByDescending(a => a.ArgumentMatch).ThenBy(a => (int)a.Constructor.ArgumentsType).First().Constructor; } args = new object[c.Args.Length]; for (var i = 0; i < c.Args.Length; i++) { String argString; if (configs.TryGetValue(c.Args[i].Name, out argString)) { args[i] = DextopUtil.DecodeValue(argString, c.Args[i].ParameterType); } } } } else { c = constructors.Where(a => a.ArgumentsType == ConstructorArgments.Array && a.Args.Length >= 1).OrderBy(a => a.Args.Length).FirstOrDefault(); if (c == null) { throw new InvalidDextopRemoteMethodCallException(); } args = new object[c.Args.Length]; args[0] = DextopUtil.DecodeValue(config, c.Args[0].ParameterType); } var remotable = (IDextopRemotable)c.ConstructorInfo.Invoke(args); try { return(new DextopRemoteMethodInvokeResult { Success = true, Result = target.Remote.TrackRemotableComponent(remotable, remoteId: options.remoteId, subRemote: options.subRemote ?? true, own: options.own ?? true ) }); } catch { remotable.Dispose(); throw; } } catch (TargetInvocationException tix) { return(new DextopRemoteMethodInvokeResult { Success = false, Exception = tix.InnerException ?? tix }); } catch (Exception ex) { return(new DextopRemoteMethodInvokeResult { Success = false, Exception = ex }); } }
public DextopRemoteMethodInvokeResult Invoke(IDextopRemotable target, string methodName, string[] arguments, DextopFormSubmit form) { if (methodName == "Instantiate" && arguments.Length > 0) { return(Instantiate(target, arguments)); } if (methodName == "Dispose") { try { target.Dispose(); return(new DextopRemoteMethodInvokeResult { Success = true }); } catch (Exception ex) { return(new DextopRemoteMethodInvokeResult { Success = false, Exception = ex }); } } try { var type = target.GetType(); var method = GetMethod(type, methodName); ++method.InvokeCount; int offset = form == null ? 0 : 1; object[] args = new object[method.Args.Length]; if (form != null) { args[0] = form; } if (arguments.Length + offset != method.Args.Length) { throw new DextopException("Invalid number of arguments for a remote method call."); } for (var i = 0; i < arguments.Length; i++) { args[i + offset] = DextopUtil.DecodeValue(arguments[i], method.Args[i + offset]); } var result = method.MethodInfo.Invoke(target, args); return(new DextopRemoteMethodInvokeResult { Success = true, Result = result }); } catch (TargetInvocationException tix) { return(new DextopRemoteMethodInvokeResult { Success = false, Exception = tix.InnerException ?? tix }); } catch (Exception ex) { return(new DextopRemoteMethodInvokeResult { Success = false, Exception = ex }); } }
DextopRemoteMethodInvokeResult Instantiate(IDextopRemotable target, String[] arguments) { try { if (arguments.Length < 1) { throw new InvalidDextopRemoteMethodCallException(); } InstantiateOptions options; if (arguments[0] != null && arguments[0].StartsWith("{")) { options = DextopUtil.Decode <InstantiateOptions>(arguments[0]); } else { options = new InstantiateOptions { subRemote = true, type = arguments[0] } }; if (options.type == null) { throw new InvalidDextopRemoteMethodCallException(); } String config = null; if (arguments.Length > 1) { config = arguments[1]; } RemotableConstructor c; if (options.type == null || !constructorCache.TryGetValue(options.type, out c)) { throw new InvalidDextopRemoteMethodCallException(); } object[] args; if (c.Args == null || c.Args.Length == 0) { args = new object[0]; } else if (c.Args.Length == 1 && c.Args[0].ParameterType == typeof(DextopConfig)) { var rc = DextopUtil.Decode(config, c.Args[0].ParameterType); args = new object[] { rc }; } else { args = new object[c.Args.Length]; if (config == null) { } else if (config.StartsWith("[")) { var argss = DextopUtil.Decode <String[]>(config); for (var i = 0; i < c.Args.Length && i < argss.Length; i++) { args[i] = DextopUtil.DecodeValue(argss[i], c.Args[i].ParameterType); } } else { var configs = DextopUtil.Decode <Dictionary <String, String> >(config) ?? new Dictionary <String, String>(); for (var i = 0; i < c.Args.Length; i++) { String argString; if (configs.TryGetValue(c.Args[i].Name, out argString)) { args[i] = DextopUtil.Decode(argString, c.Args[i].ParameterType); } } } } var remotable = (IDextopRemotable)c.ConstructorInfo.Invoke(args); try { return(new DextopRemoteMethodInvokeResult { Success = true, Result = target.Remote.TrackRemotableComponent(remotable, remoteId: options.remoteId, subRemote: options.subRemote ?? true, own: options.own ?? true ) }); } catch { remotable.Dispose(); throw; } } catch (TargetInvocationException tix) { return(new DextopRemoteMethodInvokeResult { Success = false, Exception = tix.InnerException ?? tix }); } catch (Exception ex) { return(new DextopRemoteMethodInvokeResult { Success = false, Exception = ex }); } }
DextopRemoteMethodInvokeResult Instantiate(IDextopRemotable target, String[] arguments) { try { if (arguments.Length<1) throw new InvalidDextopRemoteMethodCallException(); InstantiateOptions options; if (arguments[0]!=null && arguments[0].StartsWith("{")) options = DextopUtil.Decode<InstantiateOptions>(arguments[0]); else options = new InstantiateOptions { subRemote = true, type = arguments[0] }; if (options.type == null) throw new InvalidDextopRemoteMethodCallException(); String config = null; if (arguments.Length > 1) config = arguments[1]; RemotableConstructor c; if (options.type == null || !constructorCache.TryGetValue(options.type, out c)) throw new InvalidDextopRemoteMethodCallException(); object[] args; if (c.Args == null || c.Args.Length == 0) args = new object[0]; else if (c.Args.Length == 1 && c.Args[0].ParameterType == typeof(DextopConfig)) { var rc = DextopUtil.Decode(config, c.Args[0].ParameterType); args = new object[] { rc }; } else { args = new object[c.Args.Length]; if (config == null) { } else if (config.StartsWith("[")) { var argss = DextopUtil.Decode<String[]>(config); for (var i = 0; i < c.Args.Length && i < argss.Length; i++) args[i] = DextopUtil.DecodeValue(argss[i], c.Args[i].ParameterType); } else { var configs = DextopUtil.Decode<Dictionary<String, String>>(config) ?? new Dictionary<String, String>(); for (var i = 0; i < c.Args.Length; i++) { String argString; if (configs.TryGetValue(c.Args[i].Name, out argString)) args[i] = DextopUtil.Decode(argString, c.Args[i].ParameterType); } } } var remotable = (IDextopRemotable)c.ConstructorInfo.Invoke(args); try { return new DextopRemoteMethodInvokeResult { Success = true, Result = target.Remote.TrackRemotableComponent(remotable, remoteId: options.remoteId, subRemote: options.subRemote ?? true, own : options.own ?? true ) }; } catch { remotable.Dispose(); throw; } } catch (TargetInvocationException tix) { return new DextopRemoteMethodInvokeResult { Success = false, Exception = tix.InnerException ?? tix }; } catch (Exception ex) { return new DextopRemoteMethodInvokeResult { Success = false, Exception = ex }; } }
/// <summary> /// Registers the specified remotable. /// </summary> /// <param name="remotable">The remotable.</param> /// <param name="remoteId">The remote id.</param> /// <param name="subRemote">if set to <c>true</c> [sub remote].</param> /// <returns></returns> public DextopConfig Register(IDextopRemotable remotable, string remoteId = null, bool subRemote = true) { return(Context.Session.Register(this, remotable, remoteId, subRemote)); }
DextopRemoteMethodInvokeResult Instantiate(IDextopRemotable target, String[] arguments) { try { if (arguments.Length<1) throw new InvalidDextopRemoteMethodCallException(); InstantiateOptions options; if (arguments[0]!=null && arguments[0].StartsWith("{")) options = DextopUtil.Decode<InstantiateOptions>(arguments[0]); else options = new InstantiateOptions { subRemote = true, type = arguments[0] }; if (options.type == null) throw new InvalidDextopRemoteMethodCallException(); String config = null; if (arguments.Length > 1) config = arguments[1]; if (options.type == null) throw new InvalidDextopRemoteMethodCallException(); List<RemotableConstructor> constructors; if (!constructorCache.TryGetValue(options.type, out constructors)) { String typeName; DextopConfig routeParams; if (MatchRoutes(options.type, out typeName, out routeParams)) return Instantiate(target, new[] { typeName, DextopUtil.Encode(routeParams) }); if (constructors==null || constructors.Count == 0) constructors = LoadRemotableConstructors(options.type); } if (constructors == null || constructors.Count == 0) throw new InvalidDextopRemoteMethodCallException(); object[] args; RemotableConstructor c; if (config == null) { args = new object[0]; c = constructors.FirstOrDefault(a => a.ArgumentsType == ConstructorArgments.Default); if (c == null) { c = constructors.FirstOrDefault(a => a.ArgumentsType == ConstructorArgments.Hash); args = new object[1]; } } else if (config.StartsWith("[")) { var argss = DextopUtil.Decode<String[]>(config); c = constructors.Where(a => a.ArgumentsType == ConstructorArgments.Array && a.Args.Length >= argss.Length).OrderBy(a => a.Args.Length).FirstOrDefault(); if (c == null) c = constructors.Where(a => a.ArgumentsType == ConstructorArgments.Array).OrderByDescending(a => a.Args.Length).FirstOrDefault(); if (c == null) c = constructors.FirstOrDefault(a => a.ArgumentsType == ConstructorArgments.Hash); if (c == null) c = constructors.FirstOrDefault(a => a.ArgumentsType == ConstructorArgments.Default); if (c == null) throw new InvalidDextopRemoteMethodCallException(); args = new object[c.Args.Length]; for (var i = 0; i < c.Args.Length && i < argss.Length; i++) args[i] = DextopUtil.DecodeValue(argss[i], c.Args[i].ParameterType); } else if (config.StartsWith("{")) { c = constructors.FirstOrDefault(a => a.ArgumentsType == ConstructorArgments.Hash); if (c != null) { args = new object[1] { DextopUtil.Decode(config, c.Args[0].ParameterType) }; } else { var configs = DextopUtil.Decode<Dictionary<String, String>>(config) ?? new Dictionary<String, String>(); var candidates = constructors.Select(a => new { Constructor = a, ArgumentMatch = a.Args.Count(b => configs.ContainsKey(b.Name)) }).OrderByDescending(x => x.ArgumentMatch).ToArray(); c = null; foreach (var cand in candidates) { if (cand.ArgumentMatch == configs.Count && cand.Constructor.Args.Length == cand.ArgumentMatch) { c = cand.Constructor; break; } } if (c == null) // if we still don't have a match take the candidate with the biggest number of matching arguments, and prefer parameterless constructor if zero c = candidates.OrderByDescending(a => a.ArgumentMatch).ThenBy(a => (int)a.Constructor.ArgumentsType).First().Constructor; args = new object[c.Args.Length]; for (var i = 0; i < c.Args.Length; i++) { String argString; if (configs.TryGetValue(c.Args[i].Name, out argString)) args[i] = DextopUtil.DecodeValue(argString, c.Args[i].ParameterType); } } } else { c = constructors.Where(a => a.ArgumentsType == ConstructorArgments.Array && a.Args.Length >= 1).OrderBy(a => a.Args.Length).FirstOrDefault(); if (c == null) throw new InvalidDextopRemoteMethodCallException(); args = new object[c.Args.Length]; args[0] = DextopUtil.DecodeValue(config, c.Args[0].ParameterType); } var remotable = (IDextopRemotable)c.ConstructorInfo.Invoke(args); try { return new DextopRemoteMethodInvokeResult { Success = true, Result = target.Remote.TrackRemotableComponent(remotable, remoteId: options.remoteId, subRemote: options.subRemote ?? true, own : options.own ?? true ) }; } catch { remotable.Dispose(); throw; } } catch (TargetInvocationException tix) { return new DextopRemoteMethodInvokeResult { Success = false, Exception = tix.InnerException ?? tix }; } catch (Exception ex) { return new DextopRemoteMethodInvokeResult { Success = false, Exception = ex }; } }
internal DextopConfig Register(DextopRemote parent, IDextopRemotable remotable, String remoteId = null, bool subRemote = true) { if (remotable == null) { throw new ArgumentNullException("remotable"); } bool isClientInitiated; if (remoteId == null) { remoteId = Interlocked.Increment(ref nextRemoteId).ToString(); isClientInitiated = parent != null && parent.IsClientInitiated; } else if (subRemote) { if (parent == null) { throw new DextopInternalException(); } remoteId = parent.RemoteId + '.' + remoteId; isClientInitiated = parent.IsClientInitiated; } else { isClientInitiated = true; } var context = new RemotableContext { Remotable = remotable }; var remote = new DextopRemote(Context, remoteId, isClientInitiated); var clientTypeName = DextopApplication.MapTypeName(remotable.GetType()); try { var config = new DextopConfig(); remotable.InitRemotable(remote, config); if (!remote.IsClientInitiated) { DextopConfig remoteProxyConfig; var remoteTypeName = remote.RemoteHostType ?? clientTypeName; if (remoteTypeName != null) { config.Add("alias", remoteTypeName); remoteProxyConfig = new DextopConfig(); config.Add("remote", remoteProxyConfig); } else { remoteProxyConfig = config; } remoteProxyConfig.Add("remoteId", remoteId); remoteProxyConfig.Add("alias", DextopUtil.GetRemotingProxyTypeName(clientTypeName)); if (remote.componentsConfig != null) { remoteProxyConfig.Add("components", remote.componentsConfig); //config not needed anymore - free memory remote.componentsConfig = null; } } if (!remotables.TryAdd(remoteId, context)) { throw new DextopInternalException(); } return(config); } catch { remote.Dispose(); remotable.Dispose(); throw; } }
/// <summary> /// Registers the specified remotable. /// </summary> /// <param name="remotable">The remotable.</param> /// <param name="remoteId">The remote id.</param> /// <param name="subRemote">if set to <c>true</c> [sub remote].</param> /// <returns></returns> public DextopConfig Register(IDextopRemotable remotable, string remoteId = null, bool subRemote = true) { return Context.Session.Register(this, remotable, remoteId, subRemote); }