//----------------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.ServiceModel.Channels { using System.Collections.Generic; using System.Runtime; using System.ServiceModel.Dispatcher; class ChannelBuilder { CustomBinding binding; BindingContext context; BindingParameterCollection bindingParameters; Uri listenUri; public ChannelBuilder(BindingContext context, bool addChannelDemuxerIfRequired) { this.context = context; if (addChannelDemuxerIfRequired) { this.AddDemuxerBindingElement(context.RemainingBindingElements); } this.binding = new CustomBinding(context.Binding, context.RemainingBindingElements); this.bindingParameters = context.BindingParameters; } public ChannelBuilder(Binding binding, BindingParameterCollection bindingParameters, bool addChannelDemuxerIfRequired) { this.binding = new CustomBinding(binding); this.bindingParameters = bindingParameters; if (addChannelDemuxerIfRequired) { this.AddDemuxerBindingElement(this.binding.Elements); } } public ChannelBuilder(ChannelBuilder channelBuilder) { this.binding = new CustomBinding(channelBuilder.Binding); this.bindingParameters = channelBuilder.BindingParameters; if (this.binding.Elements.Find() == null) { throw Fx.AssertAndThrow("ChannelBuilder.ctor (this.binding.Elements.Find() != null)"); } } public CustomBinding Binding { get { return this.binding; } set { this.binding = value; } } public BindingParameterCollection BindingParameters { get { return this.bindingParameters; } set { this.bindingParameters = value; } } void AddDemuxerBindingElement(BindingElementCollection elements) { if (elements.Find() == null) { // add the channel demuxer binding element right above the transport TransportBindingElement transport = elements.Find(); if (transport == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.TransportBindingElementNotFound))); } // cache the context state in the demuxer so that the same context state can be provided to the transport // when building auxilliary channels and listeners (for ex, for security negotiation) elements.Insert(elements.IndexOf(transport), new ChannelDemuxerBindingElement(true)); } } public IChannelFactory BuildChannelFactory() { if (this.context != null) { IChannelFactory factory = this.context.BuildInnerChannelFactory(); this.context = null; return factory; } else { return this.binding.BuildChannelFactory(this.bindingParameters); } } public IChannelListener BuildChannelListener() where TChannel : class, IChannel { if (this.context != null) { IChannelListener listener = this.context.BuildInnerChannelListener(); this.listenUri = listener.Uri; this.context = null; return listener; } else { return this.binding.BuildChannelListener(this.listenUri, this.bindingParameters); } } public IChannelListener BuildChannelListener(MessageFilter filter, int priority) where TChannel : class, IChannel { this.bindingParameters.Add(new ChannelDemuxerFilter(filter, priority)); IChannelListener listener = this.BuildChannelListener(); this.bindingParameters.Remove(); return listener; } public bool CanBuildChannelFactory() { return this.binding.CanBuildChannelFactory(this.bindingParameters); } public bool CanBuildChannelListener() where TChannel : class, IChannel { return this.binding.CanBuildChannelListener(this.bindingParameters); } } }