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
- SafeArrayTypeMismatchException.cs
- FormParameter.cs
- ElementHostAutomationPeer.cs
- ThreadPool.cs
- Vector3DCollectionConverter.cs
- DrawingVisual.cs
- dbdatarecord.cs
- VarRemapper.cs
- WebServicesSection.cs
- MemberExpression.cs
- ImageFormat.cs
- SqlBooleanizer.cs
- SqlDataSourceView.cs
- UnitySerializationHolder.cs
- FormsAuthenticationTicket.cs
- BevelBitmapEffect.cs
- KeyBinding.cs
- TypeSystemProvider.cs
- ZipIOBlockManager.cs
- XmlILAnnotation.cs
- CompleteWizardStep.cs
- Binding.cs
- QueueProcessor.cs
- Oid.cs
- RadioButtonAutomationPeer.cs
- RMPermissions.cs
- TableCellCollection.cs
- XmlSchemaValidator.cs
- WorkflowOperationAsyncResult.cs
- IDispatchConstantAttribute.cs
- QueryOperationResponseOfT.cs
- mansign.cs
- GeometryCollection.cs
- DocumentationServerProtocol.cs
- ProvidersHelper.cs
- GeometryModel3D.cs
- QueryConverter.cs
- DataObjectCopyingEventArgs.cs
- MouseOverProperty.cs
- RequestCache.cs
- SequenceDesignerAccessibleObject.cs
- RenderCapability.cs
- XmlParser.cs
- WebContext.cs
- ErrorHandler.cs
- PolyQuadraticBezierSegment.cs
- CreateRefExpr.cs
- ToolStripGrip.cs
- TripleDES.cs
- FederatedMessageSecurityOverHttp.cs
- FlatButtonAppearance.cs
- SqlNodeAnnotation.cs
- StandardCommandToolStripMenuItem.cs
- XmlWhitespace.cs
- safelinkcollection.cs
- ConnectorSelectionGlyph.cs
- latinshape.cs
- SettingsBase.cs
- ProcessHostServerConfig.cs
- XmlLoader.cs
- ContentDesigner.cs
- DomNameTable.cs
- InputLangChangeRequestEvent.cs
- AsnEncodedData.cs
- TextEditorContextMenu.cs
- RuntimeArgumentHandle.cs
- SizeAnimation.cs
- SynchronizedPool.cs
- MetadataPropertyAttribute.cs
- ParamArrayAttribute.cs
- BindingMAnagerBase.cs
- SqlDependencyListener.cs
- ModelMemberCollection.cs
- FormsAuthenticationEventArgs.cs
- odbcmetadatacollectionnames.cs
- RecordConverter.cs
- ObfuscateAssemblyAttribute.cs
- PathStreamGeometryContext.cs
- __Error.cs
- AutomationIdentifierGuids.cs
- XPathBinder.cs
- NameValuePermission.cs
- WorkflowApplicationAbortedException.cs
- GeometryModel3D.cs
- MemberProjectionIndex.cs
- CategoryGridEntry.cs
- DBCommand.cs
- BeginStoryboard.cs
- XpsFilter.cs
- AssemblyBuilder.cs
- UnaryExpression.cs
- WebServiceEnumData.cs
- AdjustableArrowCap.cs
- CaseExpr.cs
- DockPattern.cs
- EventDescriptor.cs
- DataBoundControlAdapter.cs
- AutomationFocusChangedEventArgs.cs
- TraceUtils.cs
- ScriptingRoleServiceSection.cs