/// <summary> /// Adds a handler to an event of a server component. /// </summary> /// <param name="interfaceName">Name of the server component interface</param> /// <param name="correlation">Correlation information</param> /// <param name="uniqueName">Unique name of the server component instance (May left empty, if component isn´t registered with a unique name)</param> /// <param name="callContext">Call context data</param> public void AddEventHandler(string interfaceName, DelegateCorrelationInfo correlation, string uniqueName, LogicalCallContextData callContext) { if (string.IsNullOrEmpty(interfaceName)) throw new ArgumentException(LanguageResource.ArgumentException_InterfaceNameMissing, "interfaceName"); if (string.IsNullOrEmpty(uniqueName)) uniqueName = interfaceName; if (!_host.ComponentRegistry.ContainsKey(uniqueName)) throw new KeyNotFoundException(string.Format(LanguageResource.KeyNotFoundException_CannotFindComponentForInterface, interfaceName)); var details = new InvocationDetails() { InterfaceName = interfaceName, Registration = _host.ComponentRegistry[uniqueName], CallContextData = callContext }; Invoke_LoadCallContextData(details); Invoke_SetSession(details); Invoke_ResolveComponentInstance(details); var correlationSet = new List<DelegateCorrelationInfo> { correlation }; CreateClientServerWires(details.Type, details.Registration.EventStub, correlationSet, details.Registration.EventWirings); }
/// <summary> /// Handles subscription to events. /// </summary> /// <param name="methodCallMessage"><see cref="IMethodCallMessage"/> to process.</param> /// <param name="methodInfo"><see cref="MethodInfo"/> for the method being called.</param> /// <returns><see cref="ReturnMessage"/>, if the call is processed successfully, otherwise, false.</returns> private ReturnMessage HandleEventSubscription(IMethodCallMessage methodCallMessage, MethodInfo methodInfo) { // Check for delegate parameters in properties and events if (methodInfo.ReturnType.Equals(typeof(void)) && (methodCallMessage.MethodName.StartsWith("set_") || methodCallMessage.MethodName.StartsWith("add_")) && methodCallMessage.InArgCount == 1 && methodCallMessage.ArgCount == 1 && methodCallMessage.Args[0] != null && typeof(Delegate).IsAssignableFrom(methodCallMessage.Args[0].GetType())) { // Get client delegate var receiveMethodDelegate = methodCallMessage.GetArg(0) as Delegate; var eventFilter = default(IEventFilter); // Get event filter, if it is attached ExtractEventHandlerDetails(ref receiveMethodDelegate, ref eventFilter); // Trim "set_" or "add_" prefix string propertyName = methodCallMessage.MethodName.Substring(4); // Create delegate interceptor and correlation info var wiring = new DelegateInterceptor() { ClientDelegate = receiveMethodDelegate, SynchronizationContext = _synchronizationContext }; var correlationInfo = new DelegateCorrelationInfo() { IsEvent = methodCallMessage.MethodName.StartsWith("add_"), DelegateMemberName = propertyName, ClientDelegateInterceptor = wiring, EventFilter = eventFilter }; OptionalAsync(ZyanSettings.LegacyBlockingSubscriptions, () => AddRemoteEventHandlers(new List<DelegateCorrelationInfo> { correlationInfo })); // Save delegate correlation info lock (_delegateCorrelationSet) { _delegateCorrelationSet.Add(correlationInfo); } return new ReturnMessage(null, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage); } // This method doesn't represent event subscription return null; }
/// <summary> /// Removes a handler from a remote event or delegate. /// </summary> /// <param name="correlationInfo">Correlation data</param> private void RemoveRemoteEventHandler(DelegateCorrelationInfo correlationInfo) { if (correlationInfo == null) throw new ArgumentNullException("correlationInfo"); //TODO: Get rid of .NET Remoting call context. //_connection.RemoteDispatcher.RemoveEventHandler(_interfaceType.FullName, correlationInfo, _uniqueName); _connection.SendRemoveEventHandlerMessage(_interfaceType.FullName, correlationInfo, _uniqueName); }