| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- //-----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace System.ServiceModel.Dispatcher
- {
- using System;
- using System.Collections.Generic;
- using System.Reflection;
- using System.Runtime;
- using System.Runtime.Remoting.Messaging;
- using System.ServiceModel;
- using System.ServiceModel.Channels;
- using System.ServiceModel.Diagnostics.Application;
- using System.Transactions;
- class ImmutableClientRuntime
- {
- int correlationCount;
- bool addTransactionFlowProperties;
- IInteractiveChannelInitializer[] interactiveChannelInitializers;
- IClientOperationSelector operationSelector;
- IChannelInitializer[] channelInitializers;
- IClientMessageInspector[] messageInspectors;
- Dictionary<string, ProxyOperationRuntime> operations;
- ProxyOperationRuntime unhandled;
- bool useSynchronizationContext;
- bool validateMustUnderstand;
- internal ImmutableClientRuntime(ClientRuntime behavior)
- {
- this.channelInitializers = EmptyArray<IChannelInitializer>.ToArray(behavior.ChannelInitializers);
- this.interactiveChannelInitializers = EmptyArray<IInteractiveChannelInitializer>.ToArray(behavior.InteractiveChannelInitializers);
- this.messageInspectors = EmptyArray<IClientMessageInspector>.ToArray(behavior.MessageInspectors);
- this.operationSelector = behavior.OperationSelector;
- this.useSynchronizationContext = behavior.UseSynchronizationContext;
- this.validateMustUnderstand = behavior.ValidateMustUnderstand;
- this.unhandled = new ProxyOperationRuntime(behavior.UnhandledClientOperation, this);
- this.addTransactionFlowProperties = behavior.AddTransactionFlowProperties;
- this.operations = new Dictionary<string, ProxyOperationRuntime>();
- for (int i = 0; i < behavior.Operations.Count; i++)
- {
- ClientOperation operation = behavior.Operations[i];
- ProxyOperationRuntime operationRuntime = new ProxyOperationRuntime(operation, this);
- this.operations.Add(operation.Name, operationRuntime);
- }
- this.correlationCount = this.messageInspectors.Length + behavior.MaxParameterInspectors;
- }
- internal int MessageInspectorCorrelationOffset
- {
- get { return 0; }
- }
- internal int ParameterInspectorCorrelationOffset
- {
- get { return this.messageInspectors.Length; }
- }
- internal int CorrelationCount
- {
- get { return this.correlationCount; }
- }
- internal IClientOperationSelector OperationSelector
- {
- get { return this.operationSelector; }
- }
- internal ProxyOperationRuntime UnhandledProxyOperation
- {
- get { return this.unhandled; }
- }
- internal bool UseSynchronizationContext
- {
- get { return this.useSynchronizationContext; }
- }
- internal bool ValidateMustUnderstand
- {
- get { return validateMustUnderstand; }
- set { validateMustUnderstand = value; }
- }
- internal void AfterReceiveReply(ref ProxyRpc rpc)
- {
- int offset = this.MessageInspectorCorrelationOffset;
- try
- {
- for (int i = 0; i < this.messageInspectors.Length; i++)
- {
- this.messageInspectors[i].AfterReceiveReply(ref rpc.Reply, rpc.Correlation[offset + i]);
- if (TD.ClientMessageInspectorAfterReceiveInvokedIsEnabled())
- {
- TD.ClientMessageInspectorAfterReceiveInvoked(rpc.EventTraceActivity, this.messageInspectors[i].GetType().FullName);
- }
- }
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- if (ErrorBehavior.ShouldRethrowClientSideExceptionAsIs(e))
- {
- throw;
- }
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e);
- }
- }
- internal void BeforeSendRequest(ref ProxyRpc rpc)
- {
- int offset = this.MessageInspectorCorrelationOffset;
- try
- {
- for (int i = 0; i < this.messageInspectors.Length; i++)
- {
- rpc.Correlation[offset + i] = this.messageInspectors[i].BeforeSendRequest(ref rpc.Request, (IClientChannel)rpc.Channel.Proxy);
- if (TD.ClientMessageInspectorBeforeSendInvokedIsEnabled())
- {
- TD.ClientMessageInspectorBeforeSendInvoked(rpc.EventTraceActivity, this.messageInspectors[i].GetType().FullName);
- }
- }
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- if (ErrorBehavior.ShouldRethrowClientSideExceptionAsIs(e))
- {
- throw;
- }
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e);
- }
- if (this.addTransactionFlowProperties)
- {
- SendTransaction(ref rpc);
- }
- }
- internal void DisplayInitializationUI(ServiceChannel channel)
- {
- EndDisplayInitializationUI(BeginDisplayInitializationUI(channel, null, null));
- }
- internal IAsyncResult BeginDisplayInitializationUI(ServiceChannel channel, AsyncCallback callback, object state)
- {
- return new DisplayInitializationUIAsyncResult(channel, this.interactiveChannelInitializers, callback, state);
- }
- internal void EndDisplayInitializationUI(IAsyncResult result)
- {
- DisplayInitializationUIAsyncResult.End(result);
- }
- // this should not be inlined, since we want to JIT the reference to System.Transactions
- // only if transactions are being flowed.
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- static void SendTransaction(ref ProxyRpc rpc)
- {
- System.ServiceModel.Channels.TransactionFlowProperty.Set(Transaction.Current, rpc.Request);
- }
- internal void InitializeChannel(IClientChannel channel)
- {
- try
- {
- for (int i = 0; i < this.channelInitializers.Length; ++i)
- {
- this.channelInitializers[i].Initialize(channel);
- }
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- if (ErrorBehavior.ShouldRethrowClientSideExceptionAsIs(e))
- {
- throw;
- }
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e);
- }
- }
- internal ProxyOperationRuntime GetOperation(MethodBase methodBase, object[] args, out bool canCacheResult)
- {
- if (this.operationSelector == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException
- (SR.GetString(SR.SFxNeedProxyBehaviorOperationSelector2,
- methodBase.Name,
- methodBase.DeclaringType.Name)));
- }
- try
- {
- if (operationSelector.AreParametersRequiredForSelection)
- {
- canCacheResult = false;
- }
- else
- {
- args = null;
- canCacheResult = true;
- }
- string operationName = operationSelector.SelectOperation(methodBase, args);
- ProxyOperationRuntime operation;
- if ((operationName != null) && this.operations.TryGetValue(operationName, out operation))
- {
- return operation;
- }
- else
- {
- // did not find the right operation, will not know how
- // to invoke the method.
- return null;
- }
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- if (ErrorBehavior.ShouldRethrowClientSideExceptionAsIs(e))
- {
- throw;
- }
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e);
- }
- }
- internal ProxyOperationRuntime GetOperationByName(string operationName)
- {
- ProxyOperationRuntime operation = null;
- if (this.operations.TryGetValue(operationName, out operation))
- return operation;
- else
- return null;
- }
- class DisplayInitializationUIAsyncResult : System.Runtime.AsyncResult
- {
- ServiceChannel channel;
- int index = -1;
- IInteractiveChannelInitializer[] initializers;
- IClientChannel proxy;
- static AsyncCallback callback = Fx.ThunkCallback(new AsyncCallback(DisplayInitializationUIAsyncResult.Callback));
- internal DisplayInitializationUIAsyncResult(ServiceChannel channel,
- IInteractiveChannelInitializer[] initializers,
- AsyncCallback callback, object state)
- : base(callback, state)
- {
- this.channel = channel;
- this.initializers = initializers;
- this.proxy = channel.Proxy as IClientChannel;
- this.CallBegin(true);
- }
- void CallBegin(bool completedSynchronously)
- {
- while (++this.index < initializers.Length)
- {
- IAsyncResult result = null;
- Exception exception = null;
- try
- {
- result = this.initializers[this.index].BeginDisplayInitializationUI(
- this.proxy,
- DisplayInitializationUIAsyncResult.callback,
- this
- );
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- exception = e;
- }
- if (exception == null)
- {
- if (!result.CompletedSynchronously)
- {
- return;
- }
- this.CallEnd(result, out exception);
- }
- if (exception != null)
- {
- this.CallComplete(completedSynchronously, exception);
- return;
- }
- }
- this.CallComplete(completedSynchronously, null);
- }
- static void Callback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- DisplayInitializationUIAsyncResult outer = (DisplayInitializationUIAsyncResult)result.AsyncState;
- Exception exception = null;
- outer.CallEnd(result, out exception);
- if (exception != null)
- {
- outer.CallComplete(false, exception);
- return;
- }
- outer.CallBegin(false);
- }
- void CallEnd(IAsyncResult result, out Exception exception)
- {
- try
- {
- this.initializers[this.index].EndDisplayInitializationUI(result);
- exception = null;
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- exception = e;
- }
- }
- void CallComplete(bool completedSynchronously, Exception exception)
- {
- this.Complete(completedSynchronously, exception);
- }
- internal static void End(IAsyncResult result)
- {
- System.Runtime.AsyncResult.End<DisplayInitializationUIAsyncResult>(result);
- }
- }
- }
- }
|