/// <summary> /// Abonniert ein Ereignis einer Serverkomponente. /// </summary> /// <param name="interfaceName">Schnittstellenname der Serverkomponente</param> /// <param name="correlation">Korrelationsinformation</param> public void AddEventHandler(string interfaceName, DelegateCorrelationInfo correlation) { // Wenn kein Schnittstellenname angegeben wurde ... if (string.IsNullOrEmpty(interfaceName)) // Ausnahme werfen throw new ArgumentException(LanguageResource.ArgumentException_InterfaceNameMissing, "interfaceName"); // Wenn für den angegebenen Schnittstellennamen keine Komponente registriert ist ... if (!_host.ComponentRegistry.ContainsKey(interfaceName)) // Ausnahme erzeugen throw new KeyNotFoundException(string.Format("Für die angegebene Schnittstelle '{0}' ist keine Komponente registiert.", interfaceName)); // Komponentenregistrierung abrufen ComponentRegistration registration = _host.ComponentRegistry[interfaceName]; // Wenn die Komponente nicht Singletonaktiviert ist ... if (registration.ActivationType != ActivationType.Singleton) // Prozedur abbrechen return; // Komponenteninstanz erzeugen object instance = _host.GetComponentInstance(registration); // Implementierungstyp abrufen Type type = instance.GetType(); // Liste für Übergabe der Korrelationsinformation erzeugen List<DelegateCorrelationInfo> correlationSet = new List<DelegateCorrelationInfo>(); correlationSet.Add(correlation); // Client- und Server-Komponente miteinander verdrahten CreateClientServerWires(type, instance, correlationSet, registration.EventWirings); }
/// <summary> /// Removes a handler from 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 RemoveEventHandler(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 }; RemoveClientServerWires(details.Type, details.Registration.EventStub, correlationSet, details.Registration.EventWirings); }
/// <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); }
internal void SendRemoveEventHandlerMessage(string interfaceType, DelegateCorrelationInfo correlationInfo, string uniqueName) { //_connection.RemoteDispatcher.AddEventHandler(_interfaceType.FullName, correlationInfo, _uniqueName); _transportAdapter.SendRequest(new RequestMessage() { RequestType = RequestType.SystemOperation, MethodName = "RemoveEventHandler", Address = _serverUrl, ParameterValues = new object[] { interfaceType, correlationInfo, uniqueName }, CallContext = PrepareCallContext(false) }); }
/// <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> /// Entfernt das Abonnement eines Ereignisses einer Serverkomponente. /// </summary> /// <param name="interfaceName">Schnittstellenname der Serverkomponente</param> /// <param name="correlation">Korrelationsinformation</param> public void RemoveEventHandler(string interfaceName, DelegateCorrelationInfo correlation) { // Wenn kein Schnittstellenname angegeben wurde ... if (string.IsNullOrEmpty(interfaceName)) { // Ausnahme werfen throw new ArgumentException(LanguageResource.ArgumentException_InterfaceNameMissing, "interfaceName"); } // Wenn für den angegebenen Schnittstellennamen keine Komponente registriert ist ... if (!_host.ComponentRegistry.ContainsKey(interfaceName)) { // Ausnahme erzeugen throw new KeyNotFoundException(string.Format("Für die angegebene Schnittstelle '{0}' ist keine Komponente registiert.", interfaceName)); } // Komponentenregistrierung abrufen ComponentRegistration registration = _host.ComponentRegistry[interfaceName]; // Wenn die Komponente nicht Singletonaktiviert ist ... if (registration.ActivationType != ActivationType.Singleton) { // Prozedur abbrechen return; } // Komponenteninstanz erzeugen object instance = _host.GetComponentInstance(registration); // Implementierungstyp abrufen Type type = instance.GetType(); // Liste für Übergabe der Korrelationsinformation erzeugen List <DelegateCorrelationInfo> correlationSet = new List <DelegateCorrelationInfo>(); correlationSet.Add(correlation); // Client- und Server-Komponente miteinander verdrahten RemoveClientServerWires(type, instance, correlationSet, registration.EventWirings); }
/// <summary> /// Entfernte Methode aufrufen. /// </summary> /// <param name="message">Remoting-Nachricht mit Details für den entfernten Methodenaufruf</param> /// <returns>Remoting Antwortnachricht</returns> public override IMessage Invoke(IMessage message) { // Wenn keine Nachricht angegeben wurde ... if (message == null) // Ausnahme werfen throw new ArgumentNullException("message"); // Nachricht in benötigte Schnittstelle casten IMethodCallMessage methodCallMessage = (IMethodCallMessage)message; // Methoden-Metadaten abrufen MethodInfo methodInfo = (MethodInfo)methodCallMessage.MethodBase; methodInfo.GetParameters(); // Wenn die Methode ein Delegat ist ... if (methodInfo.ReturnType.Equals(typeof(void)) && methodCallMessage.InArgCount == 1 && methodCallMessage.ArgCount == 1 && methodCallMessage.Args[0] != null && typeof(Delegate).IsAssignableFrom(methodCallMessage.Args[0].GetType()) && (methodCallMessage.MethodName.StartsWith("set_") || methodCallMessage.MethodName.StartsWith("add_"))) { // Delegat auf zu verdrahtende Client-Methode abrufen object receiveMethodDelegate = methodCallMessage.GetArg(0); // "set_" wegschneiden string propertyName = methodCallMessage.MethodName.Substring(4); // Verdrahtungskonfiguration festschreiben DelegateInterceptor wiring = new DelegateInterceptor() { ClientDelegate = receiveMethodDelegate }; // Korrelationsinformation zusammenstellen DelegateCorrelationInfo correlationInfo = new DelegateCorrelationInfo() { IsEvent = methodCallMessage.MethodName.StartsWith("add_"), DelegateMemberName = propertyName, ClientDelegateInterceptor=wiring }; // Wenn die Serverkomponente Singletonaktiviert ist ... if (_activationType == ActivationType.Singleton) // Ereignis der Serverkomponente abonnieren _connection.RemoteComponentFactory.AddEventHandler(_interfaceType.FullName, correlationInfo); // Verdrahtung in der Sammlung ablegen _delegateCorrelationSet.Add(correlationInfo); // Leere Remoting-Antwortnachricht erstellen und zurückgeben return new ReturnMessage(null, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage); } else if (methodInfo.ReturnType.Equals(typeof(void)) && methodCallMessage.InArgCount == 1 && methodCallMessage.ArgCount == 1 && methodCallMessage.Args[0] != null && typeof(Delegate).IsAssignableFrom(methodCallMessage.Args[0].GetType()) && (methodCallMessage.MethodName.StartsWith("remove_"))) { // EBC-Eingangsnachricht abrufen object inputMessage = methodCallMessage.GetArg(0); // "remove_" wegschneiden string propertyName = methodCallMessage.MethodName.Substring(7); // Wenn Verdrahtungen gespeichert sind ... if (_delegateCorrelationSet.Count > 0) { // Verdrahtungskonfiguration suchen DelegateCorrelationInfo found = (from correlationInfo in (DelegateCorrelationInfo[])_delegateCorrelationSet.ToArray() where correlationInfo.DelegateMemberName.Equals(propertyName) && correlationInfo.ClientDelegateInterceptor.ClientDelegate.Equals(inputMessage) select correlationInfo).FirstOrDefault(); // Wenn eine passende Verdrahtungskonfiguration gefunden wurde ... if (found != null) { // Wenn die Serverkomponente SingleCallaktiviert ist ... if (_activationType == ActivationType.SingleCall) { // Verdrahtungskonfiguration entfernen _delegateCorrelationSet.Remove(found); } else { // Ereignisabo entfernen _connection.RemoteComponentFactory.RemoveEventHandler(_interfaceType.FullName, found); } } } // Leere Remoting-Antwortnachricht erstellen und zurückgeben return new ReturnMessage(null, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage); } else { // Aufrufkontext vorbereiten _connection.PrepareCallContext(_implicitTransactionTransfer); // Entfernten Methodenaufruf durchführen und jede Antwortnachricht sofort über einen Rückkanal empfangen return InvokeRemoteMethod(methodCallMessage); } }
/// <summary> /// Entfernte Methode aufrufen. /// </summary> /// <param name="message">Remoting-Nachricht mit Details für den entfernten Methodenaufruf</param> /// <returns>Remoting Antwortnachricht</returns> public override IMessage Invoke(IMessage message) { // Wenn keine Nachricht angegeben wurde ... if (message == null) { // Ausnahme werfen throw new ArgumentNullException("message"); } // Nachricht in benötigte Schnittstelle casten IMethodCallMessage methodCallMessage = (IMethodCallMessage)message; // Methoden-Metadaten abrufen MethodInfo methodInfo = (MethodInfo)methodCallMessage.MethodBase; methodInfo.GetParameters(); // Wenn die Methode ein Delegat ist ... if (methodInfo.ReturnType.Equals(typeof(void)) && methodCallMessage.InArgCount == 1 && methodCallMessage.ArgCount == 1 && methodCallMessage.Args[0] != null && typeof(Delegate).IsAssignableFrom(methodCallMessage.Args[0].GetType()) && (methodCallMessage.MethodName.StartsWith("set_") || methodCallMessage.MethodName.StartsWith("add_"))) { // Delegat auf zu verdrahtende Client-Methode abrufen object receiveMethodDelegate = methodCallMessage.GetArg(0); // "set_" wegschneiden string propertyName = methodCallMessage.MethodName.Substring(4); // Verdrahtungskonfiguration festschreiben DelegateInterceptor wiring = new DelegateInterceptor() { ClientDelegate = receiveMethodDelegate }; // Korrelationsinformation zusammenstellen DelegateCorrelationInfo correlationInfo = new DelegateCorrelationInfo() { IsEvent = methodCallMessage.MethodName.StartsWith("add_"), DelegateMemberName = propertyName, ClientDelegateInterceptor = wiring }; // Wenn die Serverkomponente Singletonaktiviert ist ... if (_activationType == ActivationType.Singleton) { // Ereignis der Serverkomponente abonnieren _connection.RemoteComponentFactory.AddEventHandler(_interfaceType.FullName, correlationInfo); } // Verdrahtung in der Sammlung ablegen _delegateCorrelationSet.Add(correlationInfo); // Leere Remoting-Antwortnachricht erstellen und zurückgeben return(new ReturnMessage(null, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage)); } else if (methodInfo.ReturnType.Equals(typeof(void)) && methodCallMessage.InArgCount == 1 && methodCallMessage.ArgCount == 1 && methodCallMessage.Args[0] != null && typeof(Delegate).IsAssignableFrom(methodCallMessage.Args[0].GetType()) && (methodCallMessage.MethodName.StartsWith("remove_"))) { // EBC-Eingangsnachricht abrufen object inputMessage = methodCallMessage.GetArg(0); // "remove_" wegschneiden string propertyName = methodCallMessage.MethodName.Substring(7); // Wenn Verdrahtungen gespeichert sind ... if (_delegateCorrelationSet.Count > 0) { // Verdrahtungskonfiguration suchen DelegateCorrelationInfo found = (from correlationInfo in (DelegateCorrelationInfo[])_delegateCorrelationSet.ToArray() where correlationInfo.DelegateMemberName.Equals(propertyName) && correlationInfo.ClientDelegateInterceptor.ClientDelegate.Equals(inputMessage) select correlationInfo).FirstOrDefault(); // Wenn eine passende Verdrahtungskonfiguration gefunden wurde ... if (found != null) { // Wenn die Serverkomponente SingleCallaktiviert ist ... if (_activationType == ActivationType.SingleCall) { // Verdrahtungskonfiguration entfernen _delegateCorrelationSet.Remove(found); } else { // Ereignisabo entfernen _connection.RemoteComponentFactory.RemoveEventHandler(_interfaceType.FullName, found); } } } // Leere Remoting-Antwortnachricht erstellen und zurückgeben return(new ReturnMessage(null, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage)); } else { // Aufrufkontext vorbereiten _connection.PrepareCallContext(_implicitTransactionTransfer); // Entfernten Methodenaufruf durchführen und jede Antwortnachricht sofort über einen Rückkanal empfangen return(InvokeRemoteMethod(methodCallMessage)); } }