public RpcObjectHandle AddInstance(Type interfaceType, object instance, ITransportChannel associatedChannel = null)
        {
            if (!_clientRepository && associatedChannel == null)
            {
                throw new ArgumentNullException(nameof(associatedChannel));
            }
            lock (_rpcObjects)
            {
                Purge();
                var existing = _rpcObjects.OfType <RpcObjectHandle>().FirstOrDefault(o =>
                {
                    if (o.Object.TryGetTarget(out var obj))
                    {
                        if (instance is Delegate && obj is Delegate)
                        {
                            // special handling for delegates
                            return(obj.Equals(instance));
                        }

                        return(ReferenceEquals(obj, instance));
                    }
                    return(false);
                });
                if (existing == null)
                {
                    var v = new RpcObjectHandle(instance, /*!_clientRepository*/ true); // always pin on server side as we never know when the client needs us again
                    v.AssociatedChannel = associatedChannel;
                    _rpcObjects.Add(v);
                    return(v);
                }
                return(existing);
            }
        }
        public override object GetProxyObject(IRpcChannel channel, Type[] interfaceTypes, int remoteInstanceId)
        {
            lock (_rpcObjects)
            {
                Purge();
                if (_rpcObjects.TryGetValue(RpcHandle.ComparisonHandle(remoteInstanceId), out var obj))
                {
                    if (((RpcObjectHandle)obj).Object.TryGetTarget(out var inst))
                    {
                        return(inst);
                    }
                }

                bool isDelegate = interfaceTypes.Length == 1 && interfaceTypes[0].IsSubclassOf(typeof(Delegate));

                var result = new RpcObjectHandle(null, pinned: /*isDelegate && !_clientRepository,*/ false, instanceId: remoteInstanceId);
                _rpcObjects.Add(result);

                var instance = isDelegate
                    ? ImplementDelegate(interfaceTypes[0], channel, remoteInstanceId, result.InstanceId)
                    : ImplementInterfaces(interfaceTypes, channel, remoteInstanceId, result.InstanceId);



                result.Object = new WeakReference <object>(instance);
                return(instance);
            }
        }
 public void RegisterSingleton(object singleton)
 {
     lock (_rpcObjects)
     {
         Purge();
         var v = new RpcObjectHandle(singleton, true, true);
         _rpcObjects.Add(v);
     }
 }
Beispiel #4
0
        public override object GetProxyObject(IRpcChannel channel, Type[] interfaceTypes, int remoteInstanceId)
        {
            lock (_rpcObjects)
            {
                Purge();
                if (_rpcObjects.TryGetValue(RpcHandle.ComparisonHandle(remoteInstanceId), out var obj))
                {
                    if (((RpcObjectHandle)obj).Object.TryGetTarget(out var inst))
                    {
                        return(inst);
                    }
                }

                bool isDelegate = interfaceTypes.Length == 1 && interfaceTypes[0].IsSubclassOf(typeof(Delegate));

                var result = new RpcObjectHandle(null, pinned: /*isDelegate && !_clientRepository,*/ false, instanceId: remoteInstanceId);
                _rpcObjects.Add(result);

                object instance;
                if (isDelegate)
                {
                    throw new NotSupportedException("We do not support delegates for now.");
                }
                else
                {
                    var typesHash = CreateTypesHash(interfaceTypes);
                    if (!_typeImplementations.TryGetValue(typesHash, out var implementationType))
                    {
                        throw new InvalidOperationException($"Implementation type for interfaces {string.Join(", ", interfaceTypes.Select(t => t.ToString()))} not found.");
                    }
                    var constructor = implementationType.GetConstructor(
                        BindingFlags.NonPublic | BindingFlags.Instance,
                        null,
                        new Type[] { typeof(IRpcChannel), typeof(int), typeof(int) },
                        null);
                    instance = constructor.Invoke(new object[] { channel, result.InstanceId, remoteInstanceId });
                }


                result.Object = new WeakReference <object>(instance);
                return(instance);
            }
        }