Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / ServiceChannelFactory.cs / 1 / ServiceChannelFactory.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using System.Collections.Generic; using System.Diagnostics; using System.ServiceModel.Diagnostics; using System.ServiceModel.Dispatcher; using System.ServiceModel.Description; using System.Collections.ObjectModel; using System.ServiceModel; using System.ServiceModel.Security; using System.Text; using System.Globalization; using System.Security; using System.Runtime.Remoting; abstract class ServiceChannelFactory : ChannelFactoryBase { string bindingName; ListchannelsList; ClientRuntime clientRuntime; RequestReplyCorrelator requestReplyCorrelator = new RequestReplyCorrelator(); IDefaultCommunicationTimeouts timeouts; MessageVersion messageVersion; public ServiceChannelFactory(ClientRuntime clientRuntime, Binding binding) : base() { if (clientRuntime == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("clientRuntime"); } this.bindingName = binding.Name; this.channelsList = new List (); this.clientRuntime = clientRuntime; this.timeouts = new DefaultCommunicationTimeouts(binding); this.messageVersion = binding.MessageVersion; } public ClientRuntime ClientRuntime { get { this.ThrowIfDisposed(); return this.clientRuntime; } } internal RequestReplyCorrelator RequestReplyCorrelator { get { ThrowIfDisposed(); return this.requestReplyCorrelator; } } protected override TimeSpan DefaultCloseTimeout { get { return this.timeouts.CloseTimeout; } } protected override TimeSpan DefaultReceiveTimeout { get { return this.timeouts.ReceiveTimeout; } } protected override TimeSpan DefaultOpenTimeout { get { return this.timeouts.OpenTimeout; } } protected override TimeSpan DefaultSendTimeout { get { return this.timeouts.SendTimeout; } } public MessageVersion MessageVersion { get { return this.messageVersion; } } // special overload for security only public static ServiceChannelFactory BuildChannelFactory(ChannelBuilder channelBuilder, ClientRuntime clientRuntime) { if (channelBuilder.CanBuildChannelFactory ()) { return new ServiceChannelFactoryOverDuplex(channelBuilder.BuildChannelFactory (), clientRuntime, channelBuilder.Binding); } else if (channelBuilder.CanBuildChannelFactory ()) { return new ServiceChannelFactoryOverDuplexSession(channelBuilder.BuildChannelFactory (), clientRuntime, channelBuilder.Binding); } else { return new ServiceChannelFactoryOverRequestSession(channelBuilder.BuildChannelFactory (), clientRuntime, channelBuilder.Binding, false); } } public static ServiceChannelFactory BuildChannelFactory(ServiceEndpoint serviceEndpoint) { if (serviceEndpoint == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceEndpoint"); } serviceEndpoint.EnsureInvariants(); serviceEndpoint.ValidateForClient(); ChannelRequirements requirements; ContractDescription contractDescription = serviceEndpoint.Contract; ChannelRequirements.ComputeContractRequirements(contractDescription, out requirements); BindingParameterCollection parameters; ClientRuntime clientRuntime = DispatcherBuilder.BuildProxyBehavior(serviceEndpoint, out parameters); Binding binding = serviceEndpoint.Binding; Type[] requiredChannels = ChannelRequirements.ComputeRequiredChannels(ref requirements); CustomBinding customBinding = new CustomBinding(binding); BindingContext context = new BindingContext(customBinding, parameters); InternalDuplexBindingElement internalDuplexBindingElement = null; InternalDuplexBindingElement.AddDuplexFactorySupport(context, ref internalDuplexBindingElement); customBinding = new CustomBinding(context.RemainingBindingElements); customBinding.CopyTimeouts(serviceEndpoint.Binding); foreach (Type type in requiredChannels) { if (type == typeof(IOutputChannel) && customBinding.CanBuildChannelFactory (parameters)) { return new ServiceChannelFactoryOverOutput(customBinding.BuildChannelFactory (parameters), clientRuntime, binding); } if (type == typeof(IRequestChannel) && customBinding.CanBuildChannelFactory (parameters)) { return new ServiceChannelFactoryOverRequest(customBinding.BuildChannelFactory (parameters), clientRuntime, binding); } if (type == typeof(IDuplexChannel) && customBinding.CanBuildChannelFactory (parameters)) { if (requirements.usesReply && binding.CreateBindingElements().Find ().ManualAddressing) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.CantCreateChannelWithManualAddressing))); } return new ServiceChannelFactoryOverDuplex(customBinding.BuildChannelFactory (parameters), clientRuntime, binding); } if (type == typeof(IOutputSessionChannel) && customBinding.CanBuildChannelFactory (parameters)) { return new ServiceChannelFactoryOverOutputSession(customBinding.BuildChannelFactory (parameters), clientRuntime, binding, false); } if (type == typeof(IRequestSessionChannel) && customBinding.CanBuildChannelFactory (parameters)) { return new ServiceChannelFactoryOverRequestSession(customBinding.BuildChannelFactory (parameters), clientRuntime, binding, false); } if (type == typeof(IDuplexSessionChannel) && customBinding.CanBuildChannelFactory (parameters)) { if (requirements.usesReply && binding.CreateBindingElements().Find ().ManualAddressing) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.CantCreateChannelWithManualAddressing))); } return new ServiceChannelFactoryOverDuplexSession(customBinding.BuildChannelFactory (parameters), clientRuntime, binding); } } foreach (Type type in requiredChannels) { // For SessionMode.Allowed or SessionMode.NotAllowed we will accept session-ful variants as well if (type == typeof(IOutputChannel) && customBinding.CanBuildChannelFactory (parameters)) { return new ServiceChannelFactoryOverOutputSession(customBinding.BuildChannelFactory (parameters), clientRuntime, binding, true); } if (type == typeof(IRequestChannel) && customBinding.CanBuildChannelFactory (parameters)) { return new ServiceChannelFactoryOverRequestSession(customBinding.BuildChannelFactory (parameters), clientRuntime, binding, true); } // and for SessionMode.Required, it is possible that the InstanceContextProvider is handling the session management, so // accept datagram variants if that is the case if (type == typeof(IRequestSessionChannel) && customBinding.CanBuildChannelFactory (parameters) && customBinding.GetProperty (parameters) != null) { return new ServiceChannelFactoryOverRequest(customBinding.BuildChannelFactory (parameters), clientRuntime, binding); } } // we put a lot of work into creating a good error message, as this is a common case Dictionary supportedChannels = new Dictionary (); if (customBinding.CanBuildChannelFactory (parameters)) { supportedChannels.Add(typeof(IOutputChannel), 0); } if (customBinding.CanBuildChannelFactory (parameters)) { supportedChannels.Add(typeof(IRequestChannel), 0); } if (customBinding.CanBuildChannelFactory (parameters)) { supportedChannels.Add(typeof(IDuplexChannel), 0); } if (customBinding.CanBuildChannelFactory (parameters)) { supportedChannels.Add(typeof(IOutputSessionChannel), 0); } if (customBinding.CanBuildChannelFactory (parameters)) { supportedChannels.Add(typeof(IRequestSessionChannel), 0); } if (customBinding.CanBuildChannelFactory (parameters)) { supportedChannels.Add(typeof(IDuplexSessionChannel), 0); } throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ChannelRequirements.CantCreateChannelException( supportedChannels.Keys, requiredChannels, binding.Name)); } protected override void OnAbort() { IChannel channel = null; lock (ThisLock) { channel = (channelsList.Count > 0) ? channelsList[channelsList.Count - 1] : null; } while (channel != null) { channel.Abort(); lock (ThisLock) { channelsList.Remove(channel); channel = (channelsList.Count > 0) ? channelsList[channelsList.Count - 1] : null; } } } protected override void OnClose(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); while (true) { int count; IChannel channel; lock (ThisLock) { count = channelsList.Count; if (count == 0) return; channel = channelsList[0]; } channel.Close(timeoutHelper.RemainingTime()); } } protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { List objectList; lock (ThisLock) { objectList = new List (); for (int index = 0; index < channelsList.Count; index++) objectList.Add(channelsList[index]); } return new CloseCollectionAsyncResult(timeout, callback, state, objectList); } protected override void OnEndClose(IAsyncResult result) { CloseCollectionAsyncResult.End(result); } protected override void OnOpened() { base.OnOpened(); this.clientRuntime.LockDownProperties(); } public void ChannelCreated(IChannel channel) { if (DiagnosticUtility.ShouldTraceVerbose) { DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Verbose, TraceCode.ChannelCreated, SR.GetString(SR.TraceCodeChannelCreated, DiagnosticTrace.CreateSourceString(channel)), null, null, this); } lock (ThisLock) { ThrowIfDisposed(); channelsList.Add(channel); } } public void ChannelDisposed(IChannel channel) { if (DiagnosticUtility.ShouldTraceVerbose) { DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Verbose, TraceCode.ChannelDisposed, SR.GetString(SR.TraceCodeChannelDisposed, DiagnosticTrace.CreateSourceString(channel)), null, null, this); } lock (ThisLock) { channelsList.Remove(channel); } } public virtual ServiceChannel CreateServiceChannel(EndpointAddress address, Uri via) { IChannelBinder binder = this.CreateInnerChannelBinder(address, via); ServiceChannel serviceChannel = new ServiceChannel(this, binder); if (binder is DuplexChannelBinder) { DuplexChannelBinder duplexChannelBinder = binder as DuplexChannelBinder; duplexChannelBinder.ChannelHandler = new ChannelHandler(this.messageVersion, binder, serviceChannel); duplexChannelBinder.DefaultCloseTimeout = this.DefaultCloseTimeout; duplexChannelBinder.DefaultSendTimeout = this.DefaultSendTimeout; duplexChannelBinder.IdentityVerifier = this.clientRuntime.IdentityVerifier; } return serviceChannel; } public TChannel CreateChannel (EndpointAddress address) { return this.CreateChannel (address, null); } public TChannel CreateChannel (EndpointAddress address, Uri via) { if(!this.CanCreateChannel ()) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.CouldnTCreateChannelForChannelType2, this.bindingName, typeof(TChannel).Name))); } return (TChannel)this.CreateChannel(typeof(TChannel), address, via); } public abstract bool CanCreateChannel (); public object CreateChannel(Type channelType, EndpointAddress address) { return this.CreateChannel(channelType, address, null); } public object CreateChannel(Type channelType, EndpointAddress address, Uri via) { if (via == null) { via = this.ClientRuntime.Via; if (via == null) via = address.Uri; } ServiceChannel serviceChannel = this.CreateServiceChannel(address, via); serviceChannel.Proxy = CreateProxy(channelType, channelType, MessageDirection.Input, serviceChannel); serviceChannel.ClientRuntime.GetRuntime().InitializeChannel((IClientChannel)serviceChannel.Proxy); OperationContext current = OperationContext.Current; if ((current != null) && (current.InstanceContext != null)) { current.InstanceContext.WmiChannels.Add((IChannel)serviceChannel.Proxy); serviceChannel.WmiInstanceContext = current.InstanceContext; } return serviceChannel.Proxy; } /// /// Critical - constructs a ServiceChannelProxy, which is Critical /// Safe - returns the TP, but does not return the RealProxy -- caller can't get from TP to RP without an elevation /// [SecurityCritical, SecurityTreatAsSafe] internal static object CreateProxy(Type interfaceType, Type proxiedType, MessageDirection direction, ServiceChannel serviceChannel) { if (!proxiedType.IsInterface) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("SFxChannelFactoryTypeMustBeInterface"))); } ServiceChannelProxy proxy = new ServiceChannelProxy(interfaceType, proxiedType, direction, serviceChannel); return proxy.GetTransparentProxy(); } ////// Critical - calls LinkDemand method RemotingServices.GetRealProxy and access critical class ServiceChannelProxy /// Safe - gets the ServiceChannel (which is not critical) and discards the RealProxy /// [SecurityCritical, SecurityTreatAsSafe] internal static ServiceChannel GetServiceChannel(object transparentProxy) { ServiceChannelProxy proxy = RemotingServices.GetRealProxy(transparentProxy) as ServiceChannelProxy; if (proxy != null) return proxy.GetServiceChannel(); else return null; } protected abstract IChannelBinder CreateInnerChannelBinder(EndpointAddress address, Uri via); abstract class TypedServiceChannelFactory: ServiceChannelFactory where TChannel : class, IChannel { IChannelFactory innerChannelFactory; protected TypedServiceChannelFactory(IChannelFactory innerChannelFactory, ClientRuntime clientRuntime, Binding binding) : base(clientRuntime, binding) { this.innerChannelFactory = innerChannelFactory; } protected IChannelFactory InnerChannelFactory { get { return this.innerChannelFactory; } } protected override void OnAbort() { base.OnAbort(); this.innerChannelFactory.Abort(); } protected override void OnOpen(TimeSpan timeout) { this.innerChannelFactory.Open(timeout); } protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { return this.innerChannelFactory.BeginOpen(timeout, callback, state); } protected override void OnEndOpen(IAsyncResult result) { this.innerChannelFactory.EndOpen(result); } protected override void OnClose(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); base.OnClose(timeoutHelper.RemainingTime()); this.innerChannelFactory.Close(timeoutHelper.RemainingTime()); } protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { return new ChainedAsyncResult(timeout, callback, state, base.OnBeginClose, base.OnEndClose, this.innerChannelFactory.BeginClose, this.innerChannelFactory.EndClose); } protected override void OnEndClose(IAsyncResult result) { ChainedAsyncResult.End(result); } public override T GetProperty () { if (typeof(T) == typeof(TypedServiceChannelFactory )) { return (T)(object)this; } T baseProperty = base.GetProperty (); if (baseProperty != null) { return baseProperty; } return this.innerChannelFactory.GetProperty (); } } class ServiceChannelFactoryOverOutput : TypedServiceChannelFactory { public ServiceChannelFactoryOverOutput(IChannelFactory innerChannelFactory, ClientRuntime clientRuntime, Binding binding) : base(innerChannelFactory, clientRuntime, binding) { } protected override IChannelBinder CreateInnerChannelBinder(EndpointAddress to, Uri via) { return new OutputChannelBinder(this.InnerChannelFactory.CreateChannel(to, via)); } public override bool CanCreateChannel () { return (typeof(TChannel) == typeof(IOutputChannel) || typeof(TChannel) == typeof(IRequestChannel)); } } class ServiceChannelFactoryOverDuplex : TypedServiceChannelFactory { public ServiceChannelFactoryOverDuplex(IChannelFactory innerChannelFactory, ClientRuntime clientRuntime, Binding binding) : base(innerChannelFactory, clientRuntime, binding) { } protected override IChannelBinder CreateInnerChannelBinder(EndpointAddress to, Uri via) { return new DuplexChannelBinder(this.InnerChannelFactory.CreateChannel(to, via), this.RequestReplyCorrelator); } public override bool CanCreateChannel () { return (typeof(TChannel) == typeof(IOutputChannel) || typeof(TChannel) == typeof(IRequestChannel) || typeof(TChannel) == typeof(IDuplexChannel)); } } class ServiceChannelFactoryOverRequest : TypedServiceChannelFactory { public ServiceChannelFactoryOverRequest(IChannelFactory innerChannelFactory, ClientRuntime clientRuntime, Binding binding) : base(innerChannelFactory, clientRuntime, binding) { } protected override IChannelBinder CreateInnerChannelBinder(EndpointAddress to, Uri via) { return new RequestChannelBinder(this.InnerChannelFactory.CreateChannel(to, via)); } public override bool CanCreateChannel () { return (typeof(TChannel) == typeof(IOutputChannel) || typeof(TChannel) == typeof(IRequestChannel)); } } class ServiceChannelFactoryOverOutputSession : TypedServiceChannelFactory { bool datagramAdapter; public ServiceChannelFactoryOverOutputSession(IChannelFactory innerChannelFactory, ClientRuntime clientRuntime, Binding binding, bool datagramAdapter) : base(innerChannelFactory, clientRuntime, binding) { this.datagramAdapter = datagramAdapter; } protected override IChannelBinder CreateInnerChannelBinder(EndpointAddress to, Uri via) { IOutputChannel channel; if (this.datagramAdapter) { channel = DatagramAdapter.GetOutputChannel( delegate() { return this.InnerChannelFactory.CreateChannel(to, via); }, timeouts); } else { channel = this.InnerChannelFactory.CreateChannel(to, via); } return new OutputChannelBinder(channel); } public override bool CanCreateChannel () { return (typeof(TChannel) == typeof(IOutputChannel) || typeof(TChannel) == typeof(IOutputSessionChannel) || typeof(TChannel) == typeof(IRequestChannel) || typeof(TChannel) == typeof(IRequestSessionChannel)); } } class ServiceChannelFactoryOverDuplexSession : TypedServiceChannelFactory { public ServiceChannelFactoryOverDuplexSession(IChannelFactory innerChannelFactory, ClientRuntime clientRuntime, Binding binding) : base(innerChannelFactory, clientRuntime, binding) { } protected override IChannelBinder CreateInnerChannelBinder(EndpointAddress to, Uri via) { return new DuplexChannelBinder(this.InnerChannelFactory.CreateChannel(to, via), this.RequestReplyCorrelator); } public override bool CanCreateChannel () { return (typeof(TChannel) == typeof(IOutputChannel) || typeof(TChannel) == typeof(IRequestChannel) || typeof(TChannel) == typeof(IDuplexChannel) || typeof(TChannel) == typeof(IOutputSessionChannel) || typeof(TChannel) == typeof(IRequestSessionChannel) || typeof(TChannel) == typeof(IDuplexSessionChannel)); } } class ServiceChannelFactoryOverRequestSession : TypedServiceChannelFactory { bool datagramAdapter = false; public ServiceChannelFactoryOverRequestSession(IChannelFactory innerChannelFactory, ClientRuntime clientRuntime, Binding binding, bool datagramAdapter) : base(innerChannelFactory, clientRuntime, binding) { this.datagramAdapter = datagramAdapter; } protected override IChannelBinder CreateInnerChannelBinder(EndpointAddress to, Uri via) { IRequestChannel channel; if (this.datagramAdapter) { channel = DatagramAdapter.GetRequestChannel( delegate() { return this.InnerChannelFactory.CreateChannel(to, via); }, this.timeouts); } else { channel = this.InnerChannelFactory.CreateChannel(to, via); } return new RequestChannelBinder(channel); } public override bool CanCreateChannel () { return (typeof(TChannel) == typeof(IOutputChannel) || typeof(TChannel) == typeof(IOutputSessionChannel) || typeof(TChannel) == typeof(IRequestChannel) || typeof(TChannel) == typeof(IRequestSessionChannel)); } } class DefaultCommunicationTimeouts : IDefaultCommunicationTimeouts { TimeSpan closeTimeout; TimeSpan openTimeout; TimeSpan receiveTimeout; TimeSpan sendTimeout; public DefaultCommunicationTimeouts(IDefaultCommunicationTimeouts timeouts) { this.closeTimeout = timeouts.CloseTimeout; this.openTimeout = timeouts.OpenTimeout; this.receiveTimeout = timeouts.ReceiveTimeout; this.sendTimeout = timeouts.SendTimeout; } public TimeSpan CloseTimeout { get { return this.closeTimeout; } } public TimeSpan OpenTimeout { get { return this.openTimeout; } } public TimeSpan ReceiveTimeout { get { return this.receiveTimeout; } } public TimeSpan SendTimeout { get { return this.sendTimeout; } } } } } // 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
- UTF8Encoding.cs
- EntityViewGenerationConstants.cs
- pingexception.cs
- SoapConverter.cs
- BitmapCodecInfo.cs
- Parser.cs
- CodeMethodInvokeExpression.cs
- SQLDecimal.cs
- ManualResetEventSlim.cs
- XsdDuration.cs
- XmlNamespaceMappingCollection.cs
- PointCollection.cs
- UserControl.cs
- XMLDiffLoader.cs
- DictionarySectionHandler.cs
- DSGeneratorProblem.cs
- Helpers.cs
- X509AsymmetricSecurityKey.cs
- XmlDataSourceView.cs
- FormsAuthenticationEventArgs.cs
- TickBar.cs
- ViewValidator.cs
- TabControlCancelEvent.cs
- ObjectList.cs
- ActiveDesignSurfaceEvent.cs
- LeafCellTreeNode.cs
- MimeParameters.cs
- RadioButtonAutomationPeer.cs
- AttachedPropertyMethodSelector.cs
- TransformCollection.cs
- EntityClassGenerator.cs
- CachedTypeface.cs
- PhysicalFontFamily.cs
- ManagementObjectCollection.cs
- MexBindingElement.cs
- SocketAddress.cs
- TextRangeSerialization.cs
- NameNode.cs
- SafeSystemMetrics.cs
- CharacterBufferReference.cs
- URL.cs
- ConditionCollection.cs
- StreamWriter.cs
- MobileComponentEditorPage.cs
- BaseParagraph.cs
- TableProviderWrapper.cs
- DataTableTypeConverter.cs
- SqlBulkCopyColumnMappingCollection.cs
- EncodingInfo.cs
- BindingContext.cs
- CompilerLocalReference.cs
- Listbox.cs
- WmlControlAdapter.cs
- CodeConstructor.cs
- ElementNotEnabledException.cs
- BindingContext.cs
- HttpContextServiceHost.cs
- NameTable.cs
- Annotation.cs
- EventLogInformation.cs
- DockPatternIdentifiers.cs
- Thread.cs
- XmlSchemaAll.cs
- DefaultTraceListener.cs
- DropSource.cs
- SuppressMessageAttribute.cs
- ForwardPositionQuery.cs
- DefinitionProperties.cs
- SessionEndedEventArgs.cs
- ComponentSerializationService.cs
- RuntimeConfigLKG.cs
- FormViewDeletedEventArgs.cs
- DisplayMemberTemplateSelector.cs
- ServiceProviders.cs
- TableItemProviderWrapper.cs
- DataServiceClientException.cs
- Blend.cs
- TextServicesHost.cs
- GridLength.cs
- EntityViewGenerationConstants.cs
- MessageSmuggler.cs
- ProfilePropertyMetadata.cs
- RegistryPermission.cs
- QueueSurrogate.cs
- MarkupExtensionParser.cs
- OutputScopeManager.cs
- SuppressMergeCheckAttribute.cs
- ScriptManagerProxy.cs
- AudioDeviceOut.cs
- SmtpReplyReader.cs
- MDIClient.cs
- EditorPartDesigner.cs
- FixedDSBuilder.cs
- OverflowException.cs
- BindingMAnagerBase.cs
- wmiprovider.cs
- SineEase.cs
- XmlSerializationGeneratedCode.cs
- XslNumber.cs
- CopyOfAction.cs