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); } }
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); } }