Пример #1
0
        /// <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);
        }
Пример #3
0
        /// <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);
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        /// <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;
        }
Пример #7
0
        /// <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;
        }
Пример #8
0
        /// <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;
        }
Пример #9
0
        /// <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);
            }
        }
Пример #10
0
        /// <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));
            }
        }
Пример #11
0
        /// <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);
        }