CoordinationService.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / TransactionBridge / Microsoft / Transactions / Wsat / Messaging / CoordinationService.cs / 1 / CoordinationService.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

// The base representation of a WS-C/AT messaging entity 

using System; 
using System.ServiceModel.Dispatcher; 
using System.ServiceModel.Description;
using System.Collections.Generic; 
using System.Diagnostics;
using System.Globalization;
using System.Net;
using System.IdentityModel.Claims; 
using System.IdentityModel.Policy;
using System.Security.Cryptography.X509Certificates; 
using System.ServiceModel; 
using System.ServiceModel.Channels;
using System.ServiceModel.Security; 
using System.ServiceModel.Security.Tokens;
using Microsoft.Transactions.Wsat.Protocol;

namespace Microsoft.Transactions.Wsat.Messaging 
{
    [Flags] 
    enum CoordinationServiceMode 
    {
        // Sends Activation messages 
        // E.g. WS-AT transaction formatter
        Formatter = 1,

        // Sends Registration messages 
        // Receives Activation, Registration, Completion, 2PC messages
        // E.g. WS-AT protocol service 
        ProtocolService = 2, 
    }
 
    struct CoordinationServiceConfiguration
    {
        public CoordinationServiceMode Mode;
 
        public string HostName;
        public string BasePath; 
        public int HttpsPort; 

        public TimeSpan OperationTimeout; 

        public X509Certificate2 X509Certificate;
        public bool SupportingTokensEnabled;
        public bool RemoteClientsEnabled; 

        public List GlobalAclWindowsIdentities; 
        public List GlobalAclX509CertificateThumbprints; 
    }
 
    class CoordinationService
    {
        static CoordinationService()
        { 
            AppDomain.CurrentDomain.UnhandledException +=
                new UnhandledExceptionEventHandler(UnhandledExceptionHandler); 
        } 

        static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) 
        {
            if (DebugTrace.Error)
            {
                Exception e = (Exception) args.ExceptionObject; 

                DebugTrace.Trace( 
                    TraceLevel.Error, 
                    "Unhandled {0} thrown: {1}",
                    e.GetType().Name, e 
                    );
            }
        }
 
        CoordinationServiceConfiguration config;
        CoordinationServiceSecurity security; 
 
        ChannelMruCache requestReplyChannelCache;
        ChannelMruCache datagramChannelCache; 

        NamedPipeBinding namedPipeActivationBinding;
        ChannelFactory namedPipeActivationChannelFactory;
 
        WindowsRequestReplyBinding windowsActivationBinding;
        ChannelFactory windowsActivationChannelFactory; 
 
        InteropDatagramBinding interopDatagramBinding;
        ChannelFactory interopDatagramChannelFactory; 

        InteropRegistrationBinding interopRegistrationBinding;
        ChannelFactory interopRegistrationChannelFactory;
 
        InteropActivationBinding interopActivationBinding;
        ChannelFactory interopActivationChannelFactory; 
 
        GlobalAclOperationRequirement globalAclAuthz;
 
        Uri httpsBaseAddressUri;
        Uri namedPipeBaseAddressUri;
        ProtocolVersion protocolVersion;
 
        //
        // This constructor can throw MessagingInitializationException 
        // 

        public CoordinationService(CoordinationServiceConfiguration config, ProtocolVersion protocolVersion) 
        {
            this.protocolVersion = protocolVersion;

            DebugTrace.TraceEnter(this, "CoordinationService"); 

            try 
            { 
                Initialize(config);
            } 
            catch
            {
                this.Cleanup();
                throw; 
            }
            finally 
            { 
                DebugTrace.TraceLeave(this, "CoordinationService");
            } 
        }

        void Initialize(CoordinationServiceConfiguration config)
        { 
            DebugTrace.TraceEnter(this, "Initialize");
 
            this.config = config; 
            this.security = new CoordinationServiceSecurity();
 
            // Verify config mode
            if (!(config.Mode != 0 && (config.Mode & ~(CoordinationServiceMode.Formatter | CoordinationServiceMode.ProtocolService)) == 0))
            {
                // Validates that the enum value is correct. If the value 
                // is an unknown item, we have a product bug and cannot safely continue.
                DiagnosticUtility.FailFast("Invalid CoordinationServiceMode"); 
            } 

            if ((config.Mode & CoordinationServiceMode.ProtocolService) == 0) 
            {
                if (!(string.IsNullOrEmpty(config.BasePath)))
                {
                    // The config is validated on read. 
                    // At this point, any invalid config is a bug and we cannot
                    // safely continue. 
                    DiagnosticUtility.FailFast("A base path must not be provided if protocol service mode is not enabled"); 
                }
 
                if (!(string.IsNullOrEmpty(config.HostName)))
                {
                    // The config is validated on read.
                    // At this point, any invalid config is a bug and we cannot 
                    // safely continue.
                    DiagnosticUtility.FailFast("A hostname must not be provided if protocol service mode is not enabled"); 
                } 
            }
            else 
            {
                if (string.IsNullOrEmpty(config.BasePath))
                {
                    // The config is validated on read. 
                    // At this point, any invalid config is a bug and we cannot
                    // safely continue. 
                    DiagnosticUtility.FailFast("A base path must be provided if protocol service mode is enabled"); 
                }
 
                if (string.IsNullOrEmpty(config.HostName))
                {
                    // The config is validated on read.
                    // At this point, any invalid config is a bug and we cannot 
                    // safely continue.
                    DiagnosticUtility.FailFast("A hostname must be provided if protocol service mode is enabled"); 
                } 

                if (config.X509Certificate == null) 
                {
                    // The config is validated on read.
                    // At this point, any invalid config is a bug and we cannot
                    // safely continue. 
                    DiagnosticUtility.FailFast("No authentication mechanism was provided for the protocol service");
                } 
            } 

            // Initialize the global ACL 
            this.globalAclAuthz = new GlobalAclOperationRequirement(config.GlobalAclWindowsIdentities,
                                                                    config.GlobalAclX509CertificateThumbprints,
                                                                    this.protocolVersion);
 
            //
            // Build base addresses 
            // 

            if ((this.config.Mode & CoordinationServiceMode.ProtocolService) != 0) 
            {
                this.httpsBaseAddressUri = new UriBuilder(Uri.UriSchemeHttps,
                                                          this.config.HostName,
                                                          this.config.HttpsPort, 
                                                          this.config.BasePath).Uri;
 
                // The net.pipe Activation endpoint uses the host name as a discriminant 
                // for cluster scenarios with more than one service on a node.
                this.namedPipeBaseAddressUri = new UriBuilder(Uri.UriSchemeNetPipe, 
                                                              "localhost",
                                                              -1,
                                                              this.config.HostName +
                                                              "/" + 
                                                              this.config.BasePath).Uri;
            } 
 
            //
            // Create all bindings 
            //

            this.namedPipeActivationBinding = new NamedPipeBinding(this.protocolVersion);
            if (this.config.RemoteClientsEnabled) 
            {
                this.windowsActivationBinding = new WindowsRequestReplyBinding(this.protocolVersion); 
            } 

            this.interopDatagramBinding = new InteropDatagramBinding(this.protocolVersion); 
            this.interopRegistrationBinding = new InteropRegistrationBinding(this.httpsBaseAddressUri,
                                                                             this.config.SupportingTokensEnabled,
                                                                             this.protocolVersion);
            this.interopActivationBinding = new InteropActivationBinding(this.httpsBaseAddressUri, 
                                                                         this.protocolVersion);
 
            // 
            // Create channel factories
            // 

            // Set client credentials for interop using our certificate
            ClientCredentials clientCredentials = new ClientCredentials();
            clientCredentials.ClientCertificate.Certificate = this.config.X509Certificate; 
            clientCredentials.ServiceCertificate.DefaultCertificate = this.config.X509Certificate;
 
            if ((this.config.Mode & CoordinationServiceMode.ProtocolService) != 0) 
            {
                this.interopDatagramChannelFactory = CreateChannelFactory(this.interopDatagramBinding); 
                this.interopDatagramChannelFactory.Endpoint.Behaviors.Remove();
                this.interopDatagramChannelFactory.Endpoint.Behaviors.Add(clientCredentials);
                OpenChannelFactory(this.interopDatagramChannelFactory);
 
                this.interopRegistrationChannelFactory = CreateChannelFactory(this.interopRegistrationBinding);
                this.interopRegistrationChannelFactory.Endpoint.Behaviors.Remove(); 
                this.interopRegistrationChannelFactory.Endpoint.Behaviors.Add(clientCredentials); 
                OpenChannelFactory(this.interopRegistrationChannelFactory);
            } 

            if ((config.Mode & CoordinationServiceMode.Formatter) != 0)
            {
                if (this.config.X509Certificate != null) 
                {
                    this.interopActivationChannelFactory = CreateChannelFactory(this.interopActivationBinding); 
                    this.interopActivationChannelFactory.Endpoint.Behaviors.Remove(); 
                    this.interopActivationChannelFactory.Endpoint.Behaviors.Add(clientCredentials);
                    OpenChannelFactory(this.interopActivationChannelFactory); 
                }

                this.namedPipeActivationChannelFactory = CreateChannelFactory(this.namedPipeActivationBinding);
                    OpenChannelFactory(this.namedPipeActivationChannelFactory); 

                if (this.config.RemoteClientsEnabled) 
                { 
                    this.windowsActivationChannelFactory = CreateChannelFactory(this.windowsActivationBinding);
                    OpenChannelFactory(this.windowsActivationChannelFactory); 
                }
            }

            // 
            // Create channel caches
            // 
 
            // Everyone needs a request/reply cache
            this.requestReplyChannelCache = new ChannelMruCache(); 

            // Only protocol services need datagrams
            if ((this.config.Mode & CoordinationServiceMode.ProtocolService) != 0)
            { 
                this.datagramChannelCache = new ChannelMruCache();
            } 
 
            DebugTrace.TraceLeave(this, "Initialize");
        } 

        void AssertProtocolServiceMode()
        {
            if ((this.config.Mode & CoordinationServiceMode.ProtocolService) == 0) 
            {
                // We assume that the only code paths that come here 
                // are for when the mode is set to ProtocolService. 
                // Anything else violates this assumption and is a bug.
                DiagnosticUtility.FailFast("Must be in protocol service mode to create a proxy"); 
            }
        }

        public void Cleanup() 
        {
            DebugTrace.TraceEnter(this, "Cleanup"); 
 
            // Close channel factories
            if (this.namedPipeActivationChannelFactory != null) 
            {
                CloseChannelFactory(this.namedPipeActivationChannelFactory);
                this.namedPipeActivationChannelFactory = null;
            } 

            if (this.windowsActivationChannelFactory != null) 
            { 
                CloseChannelFactory(this.windowsActivationChannelFactory);
                this.windowsActivationChannelFactory = null; 
            }

            if (this.interopDatagramChannelFactory != null)
            { 
                CloseChannelFactory(this.interopDatagramChannelFactory);
                this.interopDatagramChannelFactory = null; 
            } 

            if (this.interopRegistrationChannelFactory != null) 
            {
                CloseChannelFactory(this.interopRegistrationChannelFactory);
                this.interopRegistrationChannelFactory = null;
            } 

            if (this.interopActivationChannelFactory != null) 
            { 
                CloseChannelFactory(this.interopActivationChannelFactory);
                this.interopActivationChannelFactory = null; 
            }

            DebugTrace.TraceLeave(this, "Cleanup");
        } 

        void CloseChannelFactory(ChannelFactory cf) 
        { 
            try
            { 
                cf.Close();
            }
            catch (CommunicationException e)
            { 
                DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Error);
            } 
            catch (TimeoutException e) 
            {
                DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Error); 
            }
        }

        ChannelFactory CreateChannelFactory(Binding binding) 
        {
            try 
            { 
                ChannelFactory factory = new ChannelFactory(binding);
                factory.Endpoint.Behaviors.Add(DisableTransactionFlowBehavior.Instance); 
                return factory;
            }
            catch (CommunicationException e)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessagingInitializationException(
                    SR.GetString(SR.FailedToCreateChannelFactory), e)); 
            } 
        }
 
        class DisableTransactionFlowBehavior : IEndpointBehavior
        {
            internal static DisableTransactionFlowBehavior Instance = new DisableTransactionFlowBehavior();
 
            void IEndpointBehavior.Validate(ServiceEndpoint serviceEndpoint)
            { 
            } 

            void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime runtime) 
            {
                runtime.AddTransactionFlowProperties = false;
            }
 
            void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection parameters)
            { 
            } 

            void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointListener) 
            {
            }
        }
 
        void OpenChannelFactory(ChannelFactory cf)
        { 
            try 
            {
                cf.Open(); 
            }
            // The most likely reason for this exception is that something was wrong with the
            // X509Certificate provided in configuration. We try to check it in the protocol
            // config logic, but our tests are probably not exhaustive 
            catch (ArgumentException e)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessagingInitializationException( 
                    SR.GetString(SR.FailedToOpenChannelFactory), e));
            } 
            catch (CommunicationException e)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessagingInitializationException(
                    SR.GetString(SR.FailedToOpenChannelFactory), e)); 
            }
        } 
 
        public ProtocolVersion ProtocolVersion
        { 
            get { return this.protocolVersion; }
        }

        public CoordinationServiceConfiguration Config 
        {
            get { return this.config; } 
        } 

        public CoordinationServiceSecurity Security 
        {
            get { return this.security; }
        }
 
        public GlobalAclOperationRequirement GlobalAcl
        { 
            get { return this.globalAclAuthz; } 
        }
 
        public NamedPipeBinding NamedPipeActivationBinding
        {
            get { return this.namedPipeActivationBinding; }
        } 

        public WindowsRequestReplyBinding WindowsActivationBinding 
        { 
            get { return this.windowsActivationBinding; }
        } 

        public InteropDatagramBinding InteropDatagramBinding
        {
            get { return this.interopDatagramBinding; } 
        }
 
        public InteropRequestReplyBinding InteropRegistrationBinding 
        {
            get { return this.interopRegistrationBinding; } 
        }

        public InteropRequestReplyBinding InteropActivationBinding
        { 
            get { return this.interopActivationBinding; }
        } 
 
        public IChannelFactory NamedPipeActivationChannelFactory
        { 
            get { return this.namedPipeActivationChannelFactory; }
        }

        public IChannelFactory WindowsActivationChannelFactory 
        {
            get { return this.windowsActivationChannelFactory; } 
        } 

        public IChannelFactory InteropDatagramChannelFactory 
        {
            get { return this.interopDatagramChannelFactory; }
        }
 
        public IChannelFactory InteropRegistrationChannelFactory
        { 
            get { return this.interopRegistrationChannelFactory; } 
        }
 
        public IChannelFactory InteropActivationChannelFactory
        {
            get { return this.interopActivationChannelFactory; }
        } 

        public ChannelMruCache RequestReplyChannelCache 
        { 
            get { return this.requestReplyChannelCache; }
        } 

        public ChannelMruCache DatagramChannelCache
        {
            get { return this.datagramChannelCache;  } 
        }
 
        CoordinationServiceHost CreateService(object dispatcher, 
                                              Type contract,
                                              string pathSuffix) 
        {
            CoordinationServiceHost service = new CoordinationServiceHost(this, dispatcher);
            service.InternalBaseAddresses.Add(this.httpsBaseAddressUri);
 
            // Set operation requirement for authz, turn off setting the thread principal
            ServiceAuthorizationBehavior authz = service.Description.Behaviors.Find(); 
            authz.PrincipalPermissionMode = PrincipalPermissionMode.None; 
            authz.ServiceAuthorizationManager = this.globalAclAuthz;
 
            //
            // Add endpoints
            //
 
            Binding binding;
            ServiceCredentials serverCreds; 
 
            if (dispatcher is IWSActivationCoordinator)
            { 
                service.InternalBaseAddresses.Add(this.namedPipeBaseAddressUri);
                binding = this.namedPipeActivationBinding;
                service.AddServiceEndpoint(contract, binding, pathSuffix);
 
                if (this.config.RemoteClientsEnabled)
                { 
                    // Add a remotable endpoint for activation 
                    binding = this.windowsActivationBinding;
                    service.AddServiceEndpoint(contract, binding, pathSuffix + BindingStrings.RemoteProxySuffix); 
                }

                binding = this.interopActivationBinding;
                serverCreds = new DefaultServiceCredentials(); 
            }
            else if (dispatcher is IWSRegistrationCoordinator) 
            { 
                binding = this.interopRegistrationBinding;
                if (this.config.SupportingTokensEnabled) 
                {
                    serverCreds = this.interopRegistrationBinding.SupportingTokenBindingElement.ServiceCredentials;
                }
                else 
                {
                    serverCreds = new DefaultServiceCredentials(); 
                } 
            }
            else 
            {
                binding = this.interopDatagramBinding;
                serverCreds = new DefaultServiceCredentials();
            } 

            service.AddServiceEndpoint(contract, binding, pathSuffix); 
 
            //
            // Add service credentials 
            //
            serverCreds.WindowsAuthentication.IncludeWindowsGroups = true;
            serverCreds.ServiceCertificate.Certificate = this.config.X509Certificate;
            serverCreds.ClientCertificate.Certificate = this.config.X509Certificate; 
            service.Description.Behaviors.Add(serverCreds);
 
            // 
            // Disable MeX
            // 

            ServiceMetadataBehavior mexBehavior = service.Description.Behaviors.Find();
            if (mexBehavior != null)
            { 
                if (DebugTrace.Verbose)
                { 
                    DebugTrace.Trace(TraceLevel.Verbose, "Disabling WS-MeX support"); 
                }
 
                mexBehavior.HttpGetEnabled = false;
                mexBehavior.HttpsGetEnabled = false;
            }
 
            ServiceDebugBehavior debugBehavior = service.Description.Behaviors.Find();
            if (debugBehavior != null) 
            { 
                if (DebugTrace.Verbose)
                { 
                    DebugTrace.Trace(TraceLevel.Verbose, "Disabling WS-MeX support");
                }

                debugBehavior.HttpHelpPageEnabled = false; 
                debugBehavior.HttpsHelpPageEnabled = false;
            } 
 
            // Note - the service host has not been opened yet
            return service; 
        }

        //
        // The various Add functions should never throw 
        //
 
        public ICoordinationListener Add(IActivationCoordinator serviceInstance) 
        {
            DebugTrace.TraceEnter("CoordinationService.Add (IActivationCoordinator)"); 

            this.AssertProtocolServiceMode();

            IWSActivationCoordinator activationCoordinatorDispatcher = 
                ActivationCoordinatorDispatcher.Instance(this, serviceInstance);
 
            ICoordinationListener listener = CreateService( 
                activationCoordinatorDispatcher,
                activationCoordinatorDispatcher.ContractType, 
                BindingStrings.ActivationCoordinatorSuffix(this.protocolVersion));

            DebugTrace.TraceLeave("CoordinationService.Add (IActivationCoordinator)");
            return listener; 
        }
 
        public ICoordinationListener Add(IRegistrationCoordinator serviceInstance) 
        {
            DebugTrace.TraceEnter("CoordinationService.Add (IRegistrationCoordinator)"); 

            this.AssertProtocolServiceMode();

            IWSRegistrationCoordinator registrationCoordinatorDispatcher = 
                RegistrationCoordinatorDispatcher.Instance(this, serviceInstance);
 
            ICoordinationListener listener = CreateService( 
                registrationCoordinatorDispatcher,
                registrationCoordinatorDispatcher.ContractType, 
                BindingStrings.RegistrationCoordinatorSuffix(this.protocolVersion));

            DebugTrace.TraceLeave("CoordinationService.Add (IRegistrationCoordinator)");
            return listener; 
        }
 
        public ICoordinationListener Add(ICompletionCoordinator serviceInstance) 
        {
            DebugTrace.TraceEnter("CoordinationService.Add (ICompletionCoordinator)"); 

            this.AssertProtocolServiceMode();

            IWSCompletionCoordinator completionCoordinatorDispatcher = 
                CompletionCoordinatorDispatcher.Instance(this, serviceInstance);
 
            ICoordinationListener listener = CreateService( 
                completionCoordinatorDispatcher,
                completionCoordinatorDispatcher.ContractType, 
                BindingStrings.CompletionCoordinatorSuffix(this.protocolVersion));

            DebugTrace.TraceLeave("CoordinationService.Add (ICompletionCoordinator)");
            return listener; 
        }
 
        public ICoordinationListener Add(ICompletionParticipant serviceInstance) 
        {
            DebugTrace.TraceEnter("CoordinationService.Add (ICompletionParticipant)"); 

            this.AssertProtocolServiceMode();

            IWSCompletionParticipant completionParticipantDispatcher = 
                CompletionParticipantDispatcher.Instance(this, serviceInstance);
 
            ICoordinationListener listener = CreateService( 
                completionParticipantDispatcher,
                completionParticipantDispatcher.ContractType, 
                BindingStrings.CompletionParticipantSuffix(this.protocolVersion));

            DebugTrace.TraceLeave("CoordinationService.Add (ICompletionParticipant)");
            return listener; 
        }
 
        public ICoordinationListener Add(ITwoPhaseCommitCoordinator serviceInstance) 
        {
            DebugTrace.TraceEnter("CoordinationService.Add (ITwoPhaseCommitCoordinator)"); 

            this.AssertProtocolServiceMode();

            IWSTwoPhaseCommitCoordinator twoPhaseCommitCoordinatorDispatcher = 
                TwoPhaseCommitCoordinatorDispatcher.Instance(this, serviceInstance);
 
            ICoordinationListener listener = CreateService( 
                twoPhaseCommitCoordinatorDispatcher,
                twoPhaseCommitCoordinatorDispatcher.ContractType, 
                BindingStrings.TwoPhaseCommitCoordinatorSuffix(this.protocolVersion));

            DebugTrace.TraceLeave("CoordinationService.Add (ITwoPhaseCommitCoordinator)");
            return listener; 
        }
 
        public ICoordinationListener Add(ITwoPhaseCommitParticipant serviceInstance) 
        {
            DebugTrace.TraceEnter("CoordinationService.Add (ITwoPhaseCommitParticipant)"); 

            this.AssertProtocolServiceMode();

            IWSTwoPhaseCommitParticipant twoPhaseCommitParticipantDispatcher = 
                TwoPhaseCommitParticipantDispatcher.Instance(this, serviceInstance);
 
            ICoordinationListener listener = CreateService( 
                twoPhaseCommitParticipantDispatcher,
                twoPhaseCommitParticipantDispatcher.ContractType, 
                BindingStrings.TwoPhaseCommitParticipantSuffix(this.protocolVersion));

            DebugTrace.TraceLeave("CoordinationService.Add (ITwoPhaseCommitParticipant)");
            return listener; 
        }
 
        // 
        // The various CreateProxy methods throw CreateChannelFailureException
        // 

        public ActivationProxy CreateActivationProxy(EndpointAddress to, bool interop)
        {
            if ((this.config.Mode & CoordinationServiceMode.Formatter) == 0) 
            {
                // The Formatter mode must be set in order to create an activation proxy. 
                // This error would have been caught earlier by the config reader. Missing 
                // the flag here indicates a bad code path.
                DiagnosticUtility.FailFast("Must be in formatter mode to create an activation proxy"); 
            }

            if (interop)
            { 
                return new InteropActivationProxy(this, to);
            } 
            else 
            {
                return new WindowsActivationProxy(this, to); 
            }
        }

        public RegistrationProxy CreateRegistrationProxy(EndpointAddress to) 
        {
            this.AssertProtocolServiceMode(); 
 
            return new RegistrationProxy(this, to);
        } 

        public CompletionCoordinatorProxy CreateCompletionCoordinatorProxy(EndpointAddress to,
                                                                           EndpointAddress from)
        { 
            this.AssertProtocolServiceMode();
 
            return new CompletionCoordinatorProxy(this, to, from); 
        }
 
        public CompletionParticipantProxy CreateCompletionParticipantProxy(EndpointAddress to)
        {
            this.AssertProtocolServiceMode();
 
            return new CompletionParticipantProxy(this, to);
        } 
 
        public TwoPhaseCommitCoordinatorProxy CreateTwoPhaseCommitCoordinatorProxy(EndpointAddress to,
                                                                                   EndpointAddress from) 
        {
            this.AssertProtocolServiceMode();

            return new TwoPhaseCommitCoordinatorProxy(this, to, from); 
        }
 
        public TwoPhaseCommitParticipantProxy CreateTwoPhaseCommitParticipantProxy(EndpointAddress to, 
                                                                                   EndpointAddress from)
        { 
            this.AssertProtocolServiceMode();

            return new TwoPhaseCommitParticipantProxy(this, to, from);
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK