public static ReferenceCountedChannel <TChannel> GetChannel(Proxy <TChannel> proxy)
        {
            ReferenceCountedChannel <TChannel> channel;
            EndpointAddress            to           = proxy.To;
            ChannelMruCacheKey         key          = new ChannelMruCacheKey(to.Uri.AbsoluteUri, to.Identity);
            ChannelMruCache <TChannel> channelCache = proxy.ChannelCache;

            lock (channelCache)
            {
                if (channelCache.TryGetValue(key, out channel))
                {
                    channel.AddRef();
                    return(channel);
                }
            }
            TChannel local = proxy.CreateChannel(new EndpointAddress(to.Uri, to.Identity, new AddressHeader[0]));

            lock (channelCache)
            {
                if (!channelCache.TryGetValue(key, out channel))
                {
                    channel = new ReferenceCountedChannel <TChannel>(proxy, local, key);
                    channelCache.Add(key, channel);
                }
                else
                {
                    ((IChannel)local).Close();
                }
                channel.AddRef();
            }
            return(channel);
        }
        public void OnChannelFailure()
        {
            ChannelMruCache <TChannel> channelCache = this.proxy.ChannelCache;

            lock (channelCache)
            {
                channelCache.Remove(this.key);
            }
        }
        private void Initialize(CoordinationServiceConfiguration config)
        {
            DebugTrace.TraceEnter(this, "Initialize");
            this.config   = config;
            this.security = new CoordinationServiceSecurity();
            if ((config.Mode == 0) || ((config.Mode & ~(CoordinationServiceMode.ProtocolService | CoordinationServiceMode.Formatter)) != 0))
            {
                DiagnosticUtility.FailFast("Invalid CoordinationServiceMode");
            }
            if ((config.Mode & CoordinationServiceMode.ProtocolService) == 0)
            {
                if (!string.IsNullOrEmpty(config.BasePath))
                {
                    DiagnosticUtility.FailFast("A base path must not be provided if protocol service mode is not enabled");
                }
                if (!string.IsNullOrEmpty(config.HostName))
                {
                    DiagnosticUtility.FailFast("A hostname must not be provided if protocol service mode is not enabled");
                }
            }
            else
            {
                if (string.IsNullOrEmpty(config.BasePath))
                {
                    DiagnosticUtility.FailFast("A base path must be provided if protocol service mode is enabled");
                }
                if (string.IsNullOrEmpty(config.HostName))
                {
                    DiagnosticUtility.FailFast("A hostname must be provided if protocol service mode is enabled");
                }
                if (config.X509Certificate == null)
                {
                    DiagnosticUtility.FailFast("No authentication mechanism was provided for the protocol service");
                }
            }
            this.globalAclAuthz = new GlobalAclOperationRequirement(config.GlobalAclWindowsIdentities, config.GlobalAclX509CertificateThumbprints, this.protocolVersion);
            if ((this.config.Mode & CoordinationServiceMode.ProtocolService) != 0)
            {
                this.httpsBaseAddressUri     = new UriBuilder(Uri.UriSchemeHttps, this.config.HostName, this.config.HttpsPort, this.config.BasePath).Uri;
                this.namedPipeBaseAddressUri = new UriBuilder(Uri.UriSchemeNetPipe, "localhost", -1, this.config.HostName + "/" + this.config.BasePath).Uri;
            }
            this.namedPipeActivationBinding = new NamedPipeBinding(this.protocolVersion);
            if (this.config.RemoteClientsEnabled)
            {
                this.windowsActivationBinding = new WindowsRequestReplyBinding(this.protocolVersion);
            }
            this.interopDatagramBinding     = new Microsoft.Transactions.Wsat.Messaging.InteropDatagramBinding(this.protocolVersion);
            this.interopRegistrationBinding = new Microsoft.Transactions.Wsat.Messaging.InteropRegistrationBinding(this.httpsBaseAddressUri, this.config.SupportingTokensEnabled, this.protocolVersion);
            this.interopActivationBinding   = new Microsoft.Transactions.Wsat.Messaging.InteropActivationBinding(this.httpsBaseAddressUri, this.protocolVersion);
            ClientCredentials item = new ClientCredentials {
                ClientCertificate  = { Certificate = this.config.X509Certificate },
                ServiceCertificate = { DefaultCertificate = this.config.X509Certificate }
            };

            if ((this.config.Mode & CoordinationServiceMode.ProtocolService) != 0)
            {
                this.interopDatagramChannelFactory = this.CreateChannelFactory <IDatagramService>(this.interopDatagramBinding);
                this.interopDatagramChannelFactory.Endpoint.Behaviors.Remove <ClientCredentials>();
                this.interopDatagramChannelFactory.Endpoint.Behaviors.Add(item);
                this.OpenChannelFactory <IDatagramService>(this.interopDatagramChannelFactory);
                this.interopRegistrationChannelFactory = this.CreateChannelFactory <IRequestReplyService>(this.interopRegistrationBinding);
                this.interopRegistrationChannelFactory.Endpoint.Behaviors.Remove <ClientCredentials>();
                this.interopRegistrationChannelFactory.Endpoint.Behaviors.Add(item);
                this.OpenChannelFactory <IRequestReplyService>(this.interopRegistrationChannelFactory);
            }
            if ((config.Mode & CoordinationServiceMode.Formatter) != 0)
            {
                if (this.config.X509Certificate != null)
                {
                    this.interopActivationChannelFactory = this.CreateChannelFactory <IRequestReplyService>(this.interopActivationBinding);
                    this.interopActivationChannelFactory.Endpoint.Behaviors.Remove <ClientCredentials>();
                    this.interopActivationChannelFactory.Endpoint.Behaviors.Add(item);
                    this.OpenChannelFactory <IRequestReplyService>(this.interopActivationChannelFactory);
                }
                this.namedPipeActivationChannelFactory = this.CreateChannelFactory <IRequestReplyService>(this.namedPipeActivationBinding);
                this.OpenChannelFactory <IRequestReplyService>(this.namedPipeActivationChannelFactory);
                if (this.config.RemoteClientsEnabled)
                {
                    this.windowsActivationChannelFactory = this.CreateChannelFactory <IRequestReplyService>(this.windowsActivationBinding);
                    this.OpenChannelFactory <IRequestReplyService>(this.windowsActivationChannelFactory);
                }
            }
            this.requestReplyChannelCache = new ChannelMruCache <IRequestReplyService>();
            if ((this.config.Mode & CoordinationServiceMode.ProtocolService) != 0)
            {
                this.datagramChannelCache = new ChannelMruCache <IDatagramService>();
            }
            DebugTrace.TraceLeave(this, "Initialize");
        }