/// <summary> /// Ersetzt Delegaten-Parameter einer Remoting-Nachricht durch eine entsprechende Delegaten-Abfangvorrichtung. /// </summary> /// <param name="message">Remoting-Nachricht</param> /// <returns>argumentliste</returns> private object[] InterceptDelegateParameters(IMethodCallMessage message) { // Argument-Array erzeugen object[] result = new object[message.ArgCount]; // Alle Parameter durchlaufen for (int i = 0; i < message.ArgCount; i++) { // Parameter abrufen object arg = message.Args[i]; // Wenn der aktuelle Parameter ein Delegat ist ... if (typeof(Delegate).IsAssignableFrom(arg.GetType())) { // Abfangvorrichtung erzeugen DelegateInterceptor interceptor = new DelegateInterceptor() { ClientDelegate = arg }; // Original-Parameter durch Abfangvorrichting in der Remoting-Nachricht ersetzen result[i] = interceptor; } else { // 1:1 result[i] = arg; } } // Arument-Array zurückgeben return(result); }
/// <summary> /// Erzeugt einen dynamischen Draht für ein bestimmtes Ereignis einer Komponente. /// </summary> /// <param name="componentType">Typ der Komponente</param> /// <param name="delegateType">Delegattyp</param> /// <param name="clientInterceptor">Client-Abfangvorrichtung</param> /// <returns>Instanz des passenden dynamischen Drahts</returns> public object CreateDynamicWire(Type componentType, Type delegateType, DelegateInterceptor clientInterceptor) { // Wenn kein Komponententyp angegeben wurde ... if (componentType == null) { // Ausnahme werfen throw new ArgumentNullException("componentType"); } // Wenn kein Delegattyp angegeben wurde ... if (delegateType == null) { // Ausnahme werfen throw new ArgumentNullException("delegateType"); } // Wenn keine Client-Abfangeinrichtung angegeben wurde ... if (clientInterceptor == null) { // Ausnahme werfen throw new ArgumentNullException("clientInterceptor"); } // Passenden Drahtyp erzeugen Type wireType = BuildDynamicWireType(componentType, delegateType, clientInterceptor); // Drahtinstanz erzeugen object wire = Activator.CreateInstance(wireType); // Drahtinstanz zurückgeben return(wire); }
/// <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> /// Erzeugt den Typen für einen dynamischen Draht für ein bestimmtes Ereignis einer Komponente. /// </summary> /// <param name="componentType">Typ der Komponente</param> /// <param name="delegateType">Delegattyp</param> /// <param name="clientInterceptor">Client-Abfangvorrichtung</param> /// <returns>Typ des dynamischen Drahts</returns> private Type BuildDynamicWireType(Type componentType, Type delegateType, DelegateInterceptor clientInterceptor) { // Verweise der Komponenten-Assembly übernehmen string[] references = (from assy in componentType.Assembly.GetReferencedAssemblies() select Assembly.Load(assy).Location).ToArray(); // Variable für Quellcode string sourceCode = string.Empty; // Quellcode für dynamischen Draht erzeugen sourceCode = CreateDynamicWireSourceCodeForDelegate(delegateType); // Dynamischen Draht kompilieren Assembly assembly = ScriptEngine.CompileScriptToAssembly(sourceCode, references); // Typinformationen des dynamischen Drahtes abrufen Type dynamicWireType = assembly.GetType("Zyan.Communication.DynamicWire"); // Typ des dynamischen Drahtes zurückgeben return(dynamicWireType); }
/// <summary> /// Replaces delegate parameters with call interceptors. /// </summary> /// <param name="message">Remoting message</param> /// <returns>Parameters</returns> private object[] InterceptDelegateParameters(IMethodCallMessage message) { object[] result = new object[message.ArgCount]; ParameterInfo[] paramDefs = message.MethodBase.GetParameters(); for (int i = 0; i < message.ArgCount; i++) { object arg = message.Args[i]; if (arg != null && typeof(Delegate).IsAssignableFrom(arg.GetType())) { DelegateInterceptor interceptor = new DelegateInterceptor() { ClientDelegate = arg }; result[i] = interceptor; } else { Type argType = paramDefs[i].ParameterType; Type handledType; ISerializationHandler handler; _connection.SerializationHandling.FindMatchingSerializationHandler(argType, out handledType, out handler); if (handler != null) { byte[] raw = handler.Serialize(arg); result[i] = new CustomSerializationContainer(handledType, argType, raw); } else { // 1:1 result[i] = arg; } } } return(result); }
/// <summary> /// Erzeugt den Typen für einen dynamischen Draht für ein bestimmtes Ereignis einer Komponente. /// </summary> /// <param name="componentType">Typ der Komponente</param> /// <param name="delegateType">Delegattyp</param> /// <param name="clientInterceptor">Client-Abfangvorrichtung</param> /// <returns>Typ des dynamischen Drahts</returns> private Type BuildDynamicWireType(Type componentType, Type delegateType, DelegateInterceptor clientInterceptor) { // Verweise der Komponenten-Assembly übernehmen string[] references = (from assy in componentType.Assembly.GetReferencedAssemblies() select Assembly.Load(assy).Location).ToArray(); // Variable für Quellcode string sourceCode = string.Empty; // Quellcode für dynamischen Draht erzeugen sourceCode = CreateDynamicWireSourceCodeForDelegate(delegateType); // Dynamischen Draht kompilieren Assembly assembly = ScriptEngine.CompileScriptToAssembly(sourceCode, references); // Typinformationen des dynamischen Drahtes abrufen Type dynamicWireType = assembly.GetType("Zyan.Communication.DynamicWire"); // Typ des dynamischen Drahtes zurückgeben return dynamicWireType; }
/// <summary> /// Erzeugt einen dynamischen Draht für ein bestimmtes Ereignis einer Komponente. /// </summary> /// <param name="componentType">Typ der Komponente</param> /// <param name="delegateType">Delegattyp</param> /// <param name="clientInterceptor">Client-Abfangvorrichtung</param> /// <returns>Instanz des passenden dynamischen Drahts</returns> public object CreateDynamicWire(Type componentType, Type delegateType, DelegateInterceptor clientInterceptor) { // Wenn kein Komponententyp angegeben wurde ... if (componentType == null) // Ausnahme werfen throw new ArgumentNullException("componentType"); // Wenn kein Delegattyp angegeben wurde ... if (delegateType == null) // Ausnahme werfen throw new ArgumentNullException("delegateType"); // Wenn keine Client-Abfangeinrichtung angegeben wurde ... if (clientInterceptor == null) // Ausnahme werfen throw new ArgumentNullException("clientInterceptor"); // Passenden Drahtyp erzeugen Type wireType = BuildDynamicWireType(componentType, delegateType, clientInterceptor); // Drahtinstanz erzeugen object wire = Activator.CreateInstance(wireType); // Drahtinstanz zurückgeben return wire; }
/// <summary> /// Ersetzt Delegaten-Parameter einer Remoting-Nachricht durch eine entsprechende Delegaten-Abfangvorrichtung. /// </summary> /// <param name="message">Remoting-Nachricht</param> /// <returns>argumentliste</returns> private object[] InterceptDelegateParameters(IMethodCallMessage message) { // Argument-Array erzeugen object[] result = new object[message.ArgCount]; // Alle Parameter durchlaufen for (int i = 0; i < message.ArgCount; i++) { // Parameter abrufen object arg = message.Args[i]; // Wenn der aktuelle Parameter ein Delegat ist ... if (typeof(Delegate).IsAssignableFrom(arg.GetType())) { // Abfangvorrichtung erzeugen DelegateInterceptor interceptor = new DelegateInterceptor() { ClientDelegate = arg }; // Original-Parameter durch Abfangvorrichting in der Remoting-Nachricht ersetzen result[i] = interceptor; } else // 1:1 result[i] = arg; } // Arument-Array zurückgeben return result; }
/// <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)); } }
/// <summary> /// Ruft eine bestimmte Methode einer Komponente auf und übergibt die angegebene Nachricht als Parameter. /// Für jeden Aufruf wird temporär eine neue Instanz der Komponente erstellt. /// </summary> /// <param name="trackingID">Aufrufschlüssel zur Nachverfolgung</param> /// <param name="interfaceName">Name der Komponentenschnittstelle</param> /// <param name="delegateCorrelationSet">Korrelationssatz für die Verdrahtung bestimmter Delegaten oder Ereignisse mit entfernten Methoden</param> /// <param name="methodName">Methodenname</param> /// <param name="paramDefs">Parameter-Definitionen</param> /// <param name="args">Parameter</param> /// <returns>Rückgabewert</returns> public object Invoke(Guid trackingID, string interfaceName, List <DelegateCorrelationInfo> delegateCorrelationSet, string methodName, ParameterInfo[] paramDefs, params object[] args) { // Wenn kein Schnittstellenname angegeben wurde ... if (string.IsNullOrEmpty(interfaceName)) { // Ausnahme werfen throw new ArgumentException(LanguageResource.ArgumentException_InterfaceNameMissing, "interfaceName"); } // Wenn kein Methodenname angegben wurde ... if (string.IsNullOrEmpty(methodName)) { // Ausnahme werfen throw new ArgumentException(LanguageResource.ArgumentException_MethodNameMissing, "methodName"); } // Ggf. BeforeInvoke-Abos verarbeiten ProcessBeforeInvoke(trackingID, ref interfaceName, ref delegateCorrelationSet, ref methodName, ref args); // Wenn für den angegebenen Schnittstellennamen keine Komponente registriert ist ... if (!_host.ComponentRegistry.ContainsKey(interfaceName)) { // Ausnahme erzeugen KeyNotFoundException ex = new KeyNotFoundException(string.Format("Für die angegebene Schnittstelle '{0}' ist keine Komponente registiert.", interfaceName)); // InvokeCanceled-Ereignis feuern _host.OnInvokeCanceled(new InvokeCanceledEventArgs() { TrackingID = trackingID, CancelException = ex }); // Ausnahme werfen throw ex; } // Komponentenregistrierung abrufen ComponentRegistration registration = _host.ComponentRegistry[interfaceName]; // Komponenteninstanz erzeugen object instance = _host.GetComponentInstance(registration); // Implementierungstyp abrufen Type type = instance.GetType(); // Auflistung für Ereignisverdrahtungen Dictionary <Guid, Delegate> wiringList = null; // Wenn die Komponente SingleCallaktiviert ist ... if (registration.ActivationType == ActivationType.SingleCall) { // Auflistung für Ereignisverdrahtungen erzeugen wiringList = new Dictionary <Guid, Delegate>(); // Bei Bedarf Client- und Server-Komponente miteinander verdrahten CreateClientServerWires(type, instance, delegateCorrelationSet, wiringList); } // Transaktionsbereich TransactionScope scope = null; // Kontextdaten aus dem Aufrufkontext lesen (Falls welche hinterlegt sind) LogicalCallContextData data = CallContext.GetData("__ZyanContextData_" + _host.Name) as LogicalCallContextData; // Wenn Kontextdaten übertragen wurden ... if (data != null) { // Wenn ein Sitzungsschlüssel übertragen wurde ... if (data.Store.ContainsKey("sessionid")) { // Sitzungsschlüssel lesen Guid sessionID = (Guid)data.Store["sessionid"]; // Wenn eine Sitzung mit dem angegebenen Schlüssel existiert ... if (_host.SessionManager.ExistSession(sessionID)) { // Sitzung abrufen ServerSession session = _host.SessionManager.GetSessionBySessionID(sessionID); // Sitzung verlängern session.Timestamp = DateTime.Now; // Aktuelle Sitzung im Threadspeicher ablegen ServerSession.CurrentSession = session; } else { // Ausnahme erzeugen InvalidSessionException ex = new InvalidSessionException(string.Format("Sitzungsschlüssel '{0}' ist ungültig! Bitte melden Sie sich erneut am Server an.", sessionID.ToString())); // InvokeCanceled-Ereignis feuern _host.OnInvokeCanceled(new InvokeCanceledEventArgs() { TrackingID = trackingID, CancelException = ex }); // Ausnahme werfen throw ex; } } // Wenn eine Transaktion übertragen wurde ... if (data.Store.ContainsKey("transaction")) { // Transaktionsbereich erzeugen scope = new TransactionScope((Transaction)data.Store["transaction"]); } } else { // Ausnahme erzeugen SecurityException ex = new SecurityException(LanguageResource.SecurityException_ContextInfoMissing); // InvokeCanceled-Ereignis feuern _host.OnInvokeCanceled(new InvokeCanceledEventArgs() { TrackingID = trackingID, CancelException = ex }); // Ausnahme werfen throw ex; } // Rückgabewert object returnValue = null; // Typen-Array (zur Ermittlung der passenden Signatur) erzeugen Type[] types = new Type[paramDefs.Length]; // Auflistung der Indizes von Parametern, für die eine Delegatenverdrahtung notwendig ist Dictionary <int, DelegateInterceptor> delegateParamIndexes = new Dictionary <int, DelegateInterceptor>(); // Alle Parametertypen durchlaufen for (int i = 0; i < paramDefs.Length; i++) { // Typ in Array einfügen types[i] = paramDefs[i].ParameterType; // Versuchen den aktuellen Parameter in eine Delegaten-Abfangvorrichtung zu casten DelegateInterceptor delegateParamInterceptor = args[i] as DelegateInterceptor; // Wenn aktuelle Parameter eine Delegaten-Abfangvorrichtung ist ... if (delegateParamInterceptor != null) { // Parameter der Delegaten-Verdrahtungsliste zufügen delegateParamIndexes.Add(i, delegateParamInterceptor); } } // Ausnahme-Schalter bool exceptionThrown = false; try { // Metadaten der aufzurufenden Methode abrufen MethodInfo methodInfo = type.GetMethod(methodName, types); // Metadaten der Parameter abrufen ParameterInfo[] serverMethodParamDefs = methodInfo.GetParameters(); // Delegaten-Verdrahtungsliste durchlaufen foreach (int index in delegateParamIndexes.Keys) { // Abfangvorrichtung adressieren DelegateInterceptor delegateParamInterceptor = delegateParamIndexes[index]; // Metadaten des passenden Parameters der Serverkomponenten-Methode adressieren ParameterInfo serverMethodParamDef = serverMethodParamDefs[index]; // Dynamischen Draht erzeugen object dynamicWire = DynamicWireFactory.Instance.CreateDynamicWire(type, serverMethodParamDef.ParameterType, delegateParamInterceptor); // Typ des dynamischen Drahtes ermitteln Type dynamicWireType = dynamicWire.GetType(); // Dynamischen Draht mit Client-Fernsteuerung verdrahten dynamicWireType.GetProperty("Interceptor").SetValue(dynamicWire, delegateParamInterceptor, null); // Delegat zu dynamischem Draht erzeugen Delegate dynamicWireDelegate = Delegate.CreateDelegate(serverMethodParamDef.ParameterType, dynamicWire, dynamicWireType.GetMethod("In")); // Abfangvorrichtung durch dynamischen Draht austauschen args[index] = dynamicWireDelegate; } // Methode aufrufen returnValue = methodInfo.Invoke(instance, args); } catch (Exception ex) { // Ausnahme-Schalter setzen exceptionThrown = true; // InvokeCanceled-Ereignis feuern _host.OnInvokeCanceled(new InvokeCanceledEventArgs() { TrackingID = trackingID, CancelException = ex }); // Ausnahme weiterwerfen throw ex; } finally { // Wenn ein Transaktionsbereich existiert ... if (scope != null) { // Wenn keine Ausnahme aufgetreten ist ... if (!exceptionThrown) { // Transaktionsbereich abschließen scope.Complete(); } // Transaktionsbereich entsorgen scope.Dispose(); } // Wenn die Komponente SingleCallaktiviert ist ... if (registration.ActivationType == ActivationType.SingleCall) { // Verdrahtung aufheben RemoveClientServerWires(type, instance, delegateCorrelationSet, wiringList); } } // Ggf. AfterInvoke-Abos verarbeiten ProcessAfterInvoke(trackingID, ref interfaceName, ref delegateCorrelationSet, ref methodName, ref args, ref returnValue); // Rückgabewert zurückgeben return(returnValue); }