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
- UserNameSecurityToken.cs
- BindingCompleteEventArgs.cs
- PermissionSet.cs
- LayoutTable.cs
- FilteredDataSetHelper.cs
- PropertyDescriptorCollection.cs
- SystemUnicastIPAddressInformation.cs
- DataGridRow.cs
- LinearKeyFrames.cs
- WasNotInstalledException.cs
- XmlNotation.cs
- HitTestFilterBehavior.cs
- ProfileInfo.cs
- Vector3DValueSerializer.cs
- COM2Properties.cs
- Literal.cs
- TransportSecurityHelpers.cs
- HttpUnhandledOperationInvoker.cs
- XmlSchemaChoice.cs
- SharedConnectionInfo.cs
- TextTrailingWordEllipsis.cs
- IntegerCollectionEditor.cs
- DeviceSpecific.cs
- RegexStringValidator.cs
- SimpleWorkerRequest.cs
- FileSystemWatcher.cs
- EdmMember.cs
- ResetableIterator.cs
- ClientSideQueueItem.cs
- CodeDomConfigurationHandler.cs
- Rect.cs
- TemplateKeyConverter.cs
- ProfilePropertyMetadata.cs
- DBCSCodePageEncoding.cs
- IssuedTokenClientBehaviorsElementCollection.cs
- MethodBuilder.cs
- WindowShowOrOpenTracker.cs
- UxThemeWrapper.cs
- ProcessHostServerConfig.cs
- selecteditemcollection.cs
- ConfigurationProperty.cs
- Span.cs
- SecurityRuntime.cs
- SecurityCredentialsManager.cs
- PageStatePersister.cs
- ImmutableObjectAttribute.cs
- KeyGestureConverter.cs
- DetailsViewInsertEventArgs.cs
- DataGridViewCellStyleChangedEventArgs.cs
- EndPoint.cs
- SpotLight.cs
- NativeRecognizer.cs
- PropertyFilterAttribute.cs
- UnsafeNetInfoNativeMethods.cs
- XmlSchemaSimpleType.cs
- PrintDialog.cs
- COAUTHINFO.cs
- PackWebRequestFactory.cs
- RemoteCryptoTokenProvider.cs
- ExpandCollapseProviderWrapper.cs
- XmlSchemaProviderAttribute.cs
- SizeAnimationUsingKeyFrames.cs
- AllMembershipCondition.cs
- DataContract.cs
- Guid.cs
- XmlWrappingReader.cs
- NamedPipeConnectionPoolSettingsElement.cs
- ToolStripDesignerAvailabilityAttribute.cs
- NativeStructs.cs
- WorkflowTraceTransfer.cs
- AuthenticationModuleElement.cs
- RelationshipDetailsRow.cs
- SystemIPAddressInformation.cs
- MethodBuilderInstantiation.cs
- ConnectionProviderAttribute.cs
- SizeConverter.cs
- CacheModeConverter.cs
- QueryOperatorEnumerator.cs
- UIElementPropertyUndoUnit.cs
- Funcletizer.cs
- AuthorizationSection.cs
- TreeNodeSelectionProcessor.cs
- ConfigurationPropertyCollection.cs
- BitmapSource.cs
- ModelTreeManager.cs
- FileIOPermission.cs
- SpecialFolderEnumConverter.cs
- oledbmetadatacollectionnames.cs
- ClickablePoint.cs
- MetadataStore.cs
- ClientConfigurationSystem.cs
- SqlDeflator.cs
- VisualBrush.cs
- DataPointer.cs
- MatrixTransform3D.cs
- DesignerActionGlyph.cs
- TextBoxAutomationPeer.cs
- MessageHeaderDescriptionCollection.cs
- ProxyWebPartConnectionCollection.cs
- WebPartAuthorizationEventArgs.cs