Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / ServiceChannelProxy.cs / 1 / ServiceChannelProxy.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using System.Collections; using System.ServiceModel.Dispatcher; using System.ServiceModel.Description; using System.Collections.Specialized; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.ServiceModel.Diagnostics; using System.Reflection; using System.Runtime.Remoting.Proxies; using System.Runtime.Remoting; using System.Runtime.Remoting.Messaging; using System.Security; using System.Xml; using System.Xml.Schema; ////// Critical - accesses a variety of LinkDemanded classes/methods (especially RealProxy) /// caller should protect access to the ServiceChannelProxy instance after construction /// [SecurityCritical(SecurityCriticalScope.Everything)] internal sealed class ServiceChannelProxy : RealProxy, IRemotingTypeInfo { const String activityIdSlotName = "E2ETrace.ActivityID"; Type proxiedType; Type interfaceType; ServiceChannel serviceChannel; MbrObject objectWrapper; ImmutableClientRuntime proxyRuntime; MethodDataCache methodDataCache; internal ServiceChannelProxy(Type interfaceType, Type proxiedType, MessageDirection direction, ServiceChannel serviceChannel) : base(proxiedType) { if (!MessageDirectionHelper.IsDefined(direction)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("direction")); this.interfaceType = interfaceType; this.proxiedType = proxiedType; this.serviceChannel = serviceChannel; this.proxyRuntime = serviceChannel.ClientRuntime.GetRuntime(); this.methodDataCache = new MethodDataCache(); this.objectWrapper = new MbrObject(this, proxiedType); } //Workaround is to set the activityid in remoting call's LogicalCallContext static LogicalCallContext SetActivityIdInLogicalCallContext(LogicalCallContext logicalCallContext) { logicalCallContext.SetData(activityIdSlotName, DiagnosticTrace.ActivityId); return logicalCallContext; } IMethodReturnMessage CreateReturnMessage(object ret, object[] returnArgs, IMethodCallMessage methodCall) { if (returnArgs != null) { return CreateReturnMessage(ret, returnArgs, returnArgs.Length, SetActivityIdInLogicalCallContext(methodCall.LogicalCallContext), methodCall); } else { return new SingleReturnMessage(ret, methodCall); } } IMethodReturnMessage CreateReturnMessage(object ret, object[] outArgs, int outArgsCount, LogicalCallContext callCtx, IMethodCallMessage mcm) { return new ReturnMessage(ret, outArgs, outArgsCount, callCtx, mcm); } IMethodReturnMessage CreateReturnMessage(Exception e, IMethodCallMessage mcm) { return new ReturnMessage(e, mcm); } MethodData GetMethodData(IMethodCallMessage methodCall) { MethodBase method = methodCall.MethodBase; MethodData methodData; if (methodDataCache.TryGetMethodData(method, out methodData)) { return methodData; } bool canCacheMessageData; Type declaringType = method.DeclaringType; if (declaringType == typeof(object)) { MethodType methodType; if (methodCall.MethodBase == typeof(object).GetMethod("GetType")) { methodType = MethodType.GetType; } else { methodType = MethodType.Object; } canCacheMessageData = true; methodData = new MethodData(method, methodType); } else if (declaringType.IsInstanceOfType(this.serviceChannel)) { canCacheMessageData = true; methodData = new MethodData(method, MethodType.Channel); } else { ProxyOperationRuntime operation = this.proxyRuntime.GetOperation(method, methodCall.Args, out canCacheMessageData); if (operation == null) { if (this.serviceChannel.Factory != null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SFxMethodNotSupported1, method.Name))); else throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SFxMethodNotSupportedOnCallback1, method.Name))); } MethodType methodType; if (operation.IsSyncCall(methodCall)) { methodType = MethodType.Service; } else if (operation.IsBeginCall(methodCall)) { methodType = MethodType.BeginService; } else { methodType = MethodType.EndService; } methodData = new MethodData(method, methodType, operation); } if (canCacheMessageData) { methodDataCache.SetMethodData(methodData); } return methodData; } internal ServiceChannel GetServiceChannel() { return this.serviceChannel; } public override IMessage Invoke(IMessage message) { try { IMethodCallMessage methodCall = message as IMethodCallMessage; if (methodCall == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.SFxExpectedIMethodCallMessage))); MethodData methodData = GetMethodData(methodCall); switch (methodData.MethodType) { case MethodType.Service: return InvokeService(methodCall, methodData.Operation); case MethodType.BeginService: return InvokeBeginService(methodCall, methodData.Operation); case MethodType.EndService: return InvokeEndService(methodCall, methodData.Operation); case MethodType.Channel: return InvokeChannel(methodCall); case MethodType.GetType: return InvokeGetType(methodCall); case MethodType.Object: return InvokeObject(methodCall); default: DiagnosticUtility.DebugAssert("Invalid proxy method type"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid proxy method type"))); } } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } return CreateReturnMessage(e, message as IMethodCallMessage); } } IMethodReturnMessage InvokeChannel(IMethodCallMessage methodCall) { string activityName = null; ActivityType activityType = ActivityType.Unknown; if (DiagnosticUtility.ShouldUseActivity) { if (ServiceModelActivity.Current == null || ServiceModelActivity.Current.ActivityType != ActivityType.Close) { MethodData methodData = this.GetMethodData(methodCall); if (methodData.MethodBase.DeclaringType == typeof(System.ServiceModel.ICommunicationObject) && methodData.MethodBase.Name.Equals("Close", StringComparison.Ordinal)) { activityName = SR.GetString(SR.ActivityClose, this.serviceChannel.GetType().FullName); activityType = ActivityType.Close; } } } using (ServiceModelActivity activity = string.IsNullOrEmpty(activityName) ? null :ServiceModelActivity.CreateBoundedActivity()) { if (DiagnosticUtility.ShouldUseActivity) { ServiceModelActivity.Start(activity, activityName, activityType); } return ExecuteMessage(this.serviceChannel, methodCall); } } IMethodReturnMessage InvokeGetType(IMethodCallMessage methodCall) { return CreateReturnMessage(proxiedType, null, 0, SetActivityIdInLogicalCallContext(methodCall.LogicalCallContext), methodCall); } IMethodReturnMessage InvokeObject(IMethodCallMessage methodCall) { return RemotingServices.ExecuteMessage(this.objectWrapper, methodCall); } IMethodReturnMessage InvokeBeginService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) { AsyncCallback callback; object asyncState; object[] ins = operation.MapAsyncBeginInputs(methodCall, out callback, out asyncState); object ret = this.serviceChannel.BeginCall(operation.Action, operation.IsOneWay, operation, ins, callback, asyncState); return CreateReturnMessage(ret, null, methodCall); } IMethodReturnMessage InvokeEndService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) { IAsyncResult result; object[] outs; operation.MapAsyncEndInputs(methodCall, out result, out outs); object ret = this.serviceChannel.EndCall(operation.Action, outs, result); object[] returnArgs = operation.MapAsyncOutputs(methodCall, outs, ref ret); return CreateReturnMessage(ret, returnArgs, methodCall); } IMethodReturnMessage InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) { object[] outs; object[] ins = operation.MapSyncInputs(methodCall, out outs); object ret = this.serviceChannel.Call(operation.Action, operation.IsOneWay, operation, ins, outs); object[] returnArgs = operation.MapSyncOutputs(methodCall, outs, ref ret); return CreateReturnMessage(ret, returnArgs, methodCall); } IMethodReturnMessage ExecuteMessage(object target, IMethodCallMessage methodCall) { MethodBase targetMethod = methodCall.MethodBase; object[] args = methodCall.Args; object returnValue = null; try { returnValue = targetMethod.Invoke(target, args); } catch (TargetInvocationException e) { return CreateReturnMessage(e.InnerException, methodCall); } return CreateReturnMessage(returnValue, args, args.Length, null, methodCall); } bool IRemotingTypeInfo.CanCastTo(Type toType, object o) { return toType.IsAssignableFrom(proxiedType) || serviceChannel.CanCastTo(toType); } string IRemotingTypeInfo.TypeName { get { return proxiedType.FullName; } set { } } class MethodDataCache { MethodData[] methodDatas; public MethodDataCache() { this.methodDatas = new MethodData[4]; } object ThisLock { get { return this; } } public bool TryGetMethodData(MethodBase method, out MethodData methodData) { lock (ThisLock) { MethodData[] methodDatas = this.methodDatas; int index = FindMethod(methodDatas, method); if (index >= 0) { methodData = methodDatas[index]; return true; } else { methodData = new MethodData(); return false; } } } static int FindMethod(MethodData[] methodDatas, MethodBase methodToFind) { for (int i = 0; i < methodDatas.Length; i++) { MethodBase method = methodDatas[i].MethodBase; if (method == null) { break; } if (method == methodToFind) { return i; } } return -1; } public void SetMethodData(MethodData methodData) { lock (ThisLock) { int index = FindMethod(this.methodDatas, methodData.MethodBase); if (index < 0) { for (int i = 0; i < this.methodDatas.Length; i++) { if (methodDatas[i].MethodBase == null) { methodDatas[i] = methodData; return; } } MethodData[] newMethodDatas = new MethodData[methodDatas.Length * 2]; Array.Copy(methodDatas, newMethodDatas, methodDatas.Length); newMethodDatas[methodDatas.Length] = methodData; this.methodDatas = newMethodDatas; } } } } enum MethodType { Service, BeginService, EndService, Channel, Object, GetType, } struct MethodData { MethodBase methodBase; MethodType methodType; ProxyOperationRuntime operation; public MethodData(MethodBase methodBase, MethodType methodType) : this(methodBase, methodType, null) { } public MethodData(MethodBase methodBase, MethodType methodType, ProxyOperationRuntime operation) { this.methodBase = methodBase; this.methodType = methodType; this.operation = operation; } public MethodBase MethodBase { get { return methodBase; } } public MethodType MethodType { get { return methodType; } } public ProxyOperationRuntime Operation { get { return operation; } } } class MbrObject : MarshalByRefObject { RealProxy proxy; Type targetType; internal MbrObject(RealProxy proxy, Type targetType) { this.proxy = proxy; this.targetType = targetType; } public override bool Equals(object obj) { return Object.ReferenceEquals(obj, this.proxy.GetTransparentProxy()); } public override string ToString() { return this.targetType.ToString(); } public override int GetHashCode() { return this.proxy.GetHashCode(); } } class SingleReturnMessage : IMethodReturnMessage { IMethodCallMessage methodCall; object ret; PropertyDictionary properties; public SingleReturnMessage(object ret, IMethodCallMessage methodCall) { this.ret = ret; this.methodCall = methodCall; this.properties = new PropertyDictionary(); } public int ArgCount { get { return 0; } } public object[] Args { get { return EmptyArray.Instance; } } public Exception Exception { get { return null; } } public bool HasVarArgs { get { return methodCall.HasVarArgs; } } public LogicalCallContext LogicalCallContext { get { return SetActivityIdInLogicalCallContext(methodCall.LogicalCallContext); } } public MethodBase MethodBase { get { return methodCall.MethodBase; } } public string MethodName { get { return methodCall.MethodName; } } public object MethodSignature { get { return methodCall.MethodSignature; } } public object[] OutArgs { get { return EmptyArray.Instance; } } public int OutArgCount { get { return 0; } } public IDictionary Properties { get { return properties; } } public object ReturnValue { get { return ret; } } public string TypeName { get { return methodCall.TypeName; } } public string Uri { get { return null; } } public object GetArg(int index) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("index")); } public string GetArgName(int index) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("index")); } public object GetOutArg(int index) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("index")); } public string GetOutArgName(int index) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("index")); } class PropertyDictionary : IDictionary { ListDictionary properties; public object this[object key] { get { return Properties[key]; } set { Properties[key] = value; } } public int Count { get { return Properties.Count; } } public bool IsFixedSize { get { return false; } } public bool IsReadOnly { get { return false; } } public bool IsSynchronized { get { return false; } } public ICollection Keys { get { return Properties.Keys; } } ListDictionary Properties { get { if (properties == null) { properties = new ListDictionary(); } return properties; } } public ICollection Values { get { return Properties.Values; } } public object SyncRoot { get { return null; } } public void Add(object key, object value) { Properties.Add(key, value); } public void Clear() { Properties.Clear(); } public bool Contains(object key) { return Properties.Contains(key); } public void CopyTo(Array array, int index) { Properties.CopyTo(array, index); } public IDictionaryEnumerator GetEnumerator() { if (properties == null) { return EmptyEnumerator.Instance; } else { return properties.GetEnumerator(); } } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)Properties).GetEnumerator(); } public void Remove(object key) { Properties.Remove(key); } class EmptyEnumerator : IDictionaryEnumerator { static EmptyEnumerator instance = new EmptyEnumerator(); EmptyEnumerator() { } public static EmptyEnumerator Instance { get { return instance; } } public bool MoveNext() { return false; } public Object Current { get { #pragma warning suppress 56503 // [....], IEnumerator guidelines, Current throws exception before calling MoveNext throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDictionaryIsEmpty))); } } public void Reset() { } public Object Key { get { #pragma warning suppress 56503 // [....], IEnumerator guidelines, Current throws exception before calling MoveNext throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDictionaryIsEmpty))); } } public Object Value { get { #pragma warning suppress 56503 // [....], IEnumerator guidelines, Current throws exception before calling MoveNext throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDictionaryIsEmpty))); } } public DictionaryEntry Entry { get { #pragma warning suppress 56503 // [....], IEnumerator guidelines, Current throws exception before calling MoveNext throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDictionaryIsEmpty))); } } } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- NavigatingCancelEventArgs.cs
- AnonymousIdentificationModule.cs
- OpCodes.cs
- WSFederationHttpSecurityElement.cs
- EncodingNLS.cs
- ZoomPercentageConverter.cs
- FloatAverageAggregationOperator.cs
- XmlSerializer.cs
- TextUtf8RawTextWriter.cs
- FileSecurity.cs
- JpegBitmapDecoder.cs
- CurrentChangingEventManager.cs
- DeadCharTextComposition.cs
- ChangePassword.cs
- DbDataReader.cs
- activationcontext.cs
- TraceHandler.cs
- NetMsmqSecurityMode.cs
- ListView.cs
- ReflectionTypeLoadException.cs
- SqlAliaser.cs
- DesignerSerializationManager.cs
- CommonDialog.cs
- CodeEventReferenceExpression.cs
- SessionStateItemCollection.cs
- MD5.cs
- PersonalizationStateInfoCollection.cs
- SmtpFailedRecipientException.cs
- TextEditorSelection.cs
- TextBoxBase.cs
- FormsAuthenticationCredentials.cs
- DataGridViewDataErrorEventArgs.cs
- CodeExpressionStatement.cs
- GridViewRowCollection.cs
- Vector3DConverter.cs
- HtmlTextArea.cs
- SetterBaseCollection.cs
- ImportCatalogPart.cs
- AbstractDataSvcMapFileLoader.cs
- StrokeIntersection.cs
- PagesChangedEventArgs.cs
- RepeatButtonAutomationPeer.cs
- TCEAdapterGenerator.cs
- MetabaseReader.cs
- TypeTypeConverter.cs
- processwaithandle.cs
- EventLogTraceListener.cs
- TaiwanCalendar.cs
- ScaleTransform3D.cs
- SafeProcessHandle.cs
- PixelShader.cs
- StyleCollection.cs
- StorageBasedPackageProperties.cs
- ObjectDataSource.cs
- BaseDataList.cs
- HttpHandlerAction.cs
- NativeMethods.cs
- ExecutedRoutedEventArgs.cs
- PinnedBufferMemoryStream.cs
- WebPartEditorApplyVerb.cs
- ConcurrentDictionary.cs
- DesignBindingEditor.cs
- UnhandledExceptionEventArgs.cs
- SoapAttributes.cs
- DataGridState.cs
- Header.cs
- CodeGeneratorOptions.cs
- XmlCharacterData.cs
- WindowHideOrCloseTracker.cs
- ProxyWebPartManager.cs
- localization.cs
- hresults.cs
- TypeGeneratedEventArgs.cs
- ImmutableCommunicationTimeouts.cs
- ActionFrame.cs
- ListViewUpdateEventArgs.cs
- Enum.cs
- Int16Storage.cs
- WindowsGraphicsCacheManager.cs
- MatrixAnimationUsingPath.cs
- TypeReference.cs
- DesignerActionVerbList.cs
- RecognizedWordUnit.cs
- ToolStripRenderEventArgs.cs
- SupportedAddressingMode.cs
- EmptyTextWriter.cs
- CustomExpressionEventArgs.cs
- SourceSwitch.cs
- SrgsElementList.cs
- ConnectionPointConverter.cs
- DeferredElementTreeState.cs
- NamespaceTable.cs
- Helper.cs
- XmlSchemaImporter.cs
- SafeFreeMibTable.cs
- SessionPageStateSection.cs
- TransactionState.cs
- ContextMenuStripGroupCollection.cs
- SettingsProperty.cs
- DataReaderContainer.cs