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
- StatusBarPanel.cs
- Roles.cs
- LayoutExceptionEventArgs.cs
- IpcChannel.cs
- Underline.cs
- EmptyEnumerator.cs
- DeriveBytes.cs
- InvokePattern.cs
- RelationshipEntry.cs
- DebugView.cs
- regiisutil.cs
- PropertySegmentSerializationProvider.cs
- XmlSchemaSet.cs
- RijndaelManaged.cs
- GenerateHelper.cs
- AttachedProperty.cs
- SchemaNamespaceManager.cs
- RequestCachingSection.cs
- DataPagerFieldCommandEventArgs.cs
- PerformanceCounterPermission.cs
- SiteMapSection.cs
- ActivationArguments.cs
- DataGridViewColumnCollection.cs
- Contracts.cs
- bindurihelper.cs
- ImageButton.cs
- XamlDesignerSerializationManager.cs
- FocusTracker.cs
- DataGridViewSelectedCellsAccessibleObject.cs
- PackageDigitalSignatureManager.cs
- HttpChannelHelper.cs
- UrlAuthorizationModule.cs
- ProxyHwnd.cs
- WsatAdminException.cs
- WindowsIPAddress.cs
- DataGridViewComponentPropertyGridSite.cs
- LogEntry.cs
- DbReferenceCollection.cs
- SkipStoryboardToFill.cs
- ProfileBuildProvider.cs
- DataSourceXmlElementAttribute.cs
- CollectionViewGroupRoot.cs
- TokenBasedSet.cs
- PrimitiveType.cs
- BamlReader.cs
- UnsafeNativeMethodsCLR.cs
- ElementInit.cs
- Quaternion.cs
- VariantWrapper.cs
- WorkflowPageSetupDialog.cs
- XmlSchemaGroupRef.cs
- SqlXmlStorage.cs
- HttpHandlerAction.cs
- BindingListCollectionView.cs
- RegexCaptureCollection.cs
- Baml2006ReaderFrame.cs
- TypeLoadException.cs
- RecordConverter.cs
- HMACMD5.cs
- WebPartDisplayMode.cs
- SwitchLevelAttribute.cs
- ResourceDictionary.cs
- StructuredTypeEmitter.cs
- DateTimeFormatInfoScanner.cs
- TypeSemantics.cs
- PingOptions.cs
- FontSizeConverter.cs
- PersonalizableAttribute.cs
- BindToObject.cs
- DataGridClipboardHelper.cs
- SyndicationItemFormatter.cs
- ScriptResourceAttribute.cs
- ServiceManager.cs
- Expression.cs
- ModelVisual3D.cs
- SupportsPreviewControlAttribute.cs
- InvalidProgramException.cs
- ComponentResourceKey.cs
- WpfGeneratedKnownProperties.cs
- HttpMethodAttribute.cs
- WarningException.cs
- DataControlPagerLinkButton.cs
- SvcMapFileLoader.cs
- ConsumerConnectionPoint.cs
- TimeSpanHelper.cs
- GroupBox.cs
- TrackingMemoryStreamFactory.cs
- DataGridAutomationPeer.cs
- X509UI.cs
- DataTableMappingCollection.cs
- RectIndependentAnimationStorage.cs
- RangeValidator.cs
- NextPreviousPagerField.cs
- ConnectionInterfaceCollection.cs
- XmlElementCollection.cs
- ChildrenQuery.cs
- WSAddressing10ProblemHeaderQNameFault.cs
- ChannelServices.cs
- TabPanel.cs
- WebServiceParameterData.cs