ChannelFactory.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 / ServiceModel / System / ServiceModel / ChannelFactory.cs / 1 / ChannelFactory.cs

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

namespace System.ServiceModel 
{
    using System.Collections.Generic; 
    using System.ServiceModel.Dispatcher; 
    using System.ServiceModel.Description;
    using System.Collections.ObjectModel; 
    using System.Diagnostics;
    using System.IO;
    using System.Runtime.Serialization;
    using System.Text; 
    using System.Threading;
    using System.ServiceModel.Channels; 
    using System.ServiceModel.Diagnostics; 
    using System.ServiceModel.Configuration;
    using System.ServiceModel.Security; 

    public abstract class ChannelFactory : CommunicationObject, IChannelFactory, IDisposable
    {
        string configurationName; 
        IChannelFactory innerFactory;
        ServiceEndpoint serviceEndpoint; 
        ClientCredentials readOnlyClientCredentials; 
        object openLock = new object();
 
        //Overload for activation DuplexChannelFactory
        protected ChannelFactory()
            : base()
        { 
            this.TraceOpenAndClose = true;
        } 
 
        protected void EnsureOpened()
        { 
            base.ThrowIfDisposed();
            if (this.State != CommunicationState.Opened)
            {
                lock (this.openLock) 
                {
                    if (this.State != CommunicationState.Opened) 
                    { 
                        this.Open();
                    } 
                }
            }
        }
 
        public ClientCredentials Credentials
        { 
            get 
            {
                if (this.Endpoint == null) 
                    return null;
                if (this.State == CommunicationState.Created || this.State == CommunicationState.Opening)
                {
                    return EnsureCredentials(this.Endpoint); 
                }
                else 
                { 
                    if (this.readOnlyClientCredentials == null)
                    { 
                        ClientCredentials c = new ClientCredentials();
                        c.MakeReadOnly();
                        this.readOnlyClientCredentials = c;
                    } 
                    return this.readOnlyClientCredentials;
                } 
            } 
        }
 
        protected override TimeSpan DefaultCloseTimeout
        {
            get
            { 
                if (this.Endpoint != null && this.Endpoint.Binding != null)
                { 
                    return this.Endpoint.Binding.CloseTimeout; 
                }
                else 
                {
                    return ServiceDefaults.CloseTimeout;
                }
            } 
        }
 
        protected override TimeSpan DefaultOpenTimeout 
        {
            get 
            {
                if (this.Endpoint != null && this.Endpoint.Binding != null)
                {
                    return this.Endpoint.Binding.OpenTimeout; 
                }
                else 
                { 
                    return ServiceDefaults.OpenTimeout;
                } 
            }
        }

        public ServiceEndpoint Endpoint 
        {
            get 
            { 
                return this.serviceEndpoint;
            } 
        }

        internal IChannelFactory InnerFactory
        { 
            get { return this.innerFactory; }
        } 
 
        // configurationName can be:
        // 1. null: don't bind any per-endpoint config (load common behaviors only) 
        // 2. "*" (wildcard): match any endpoint config provided there's exactly 1
        // 3. anything else (including ""): match the endpoint config with the same name
        protected virtual void ApplyConfiguration(string configurationName)
        { 
            if (this.Endpoint == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxChannelFactoryCannotApplyConfigurationWithoutEndpoint))); 
            }
 
            ConfigLoader configLoader = new ConfigLoader();
            if (configurationName == null)
            {
                configLoader.LoadCommonClientBehaviors(this.Endpoint); 
            }
            else 
            { 
                configLoader.LoadChannelBehaviors(this.Endpoint, configurationName);
            } 
        }

        protected abstract ServiceEndpoint CreateDescription();
 
        internal EndpointAddress CreateEndpointAddress(ServiceEndpoint endpoint)
        { 
            if (endpoint.Address == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxChannelFactoryEndpointAddressUri))); 
            }

            return endpoint.Address;
        } 

        protected virtual IChannelFactory CreateFactory() 
        { 
            if (this.Endpoint == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxChannelFactoryCannotCreateFactoryWithoutDescription)));
            }

            if (this.Endpoint.Binding == null) 
            {
                if (this.configurationName != null) 
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxChannelFactoryNoBindingFoundInConfig1, configurationName)));
                } 
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxChannelFactoryNoBindingFoundInConfigOrCode)));
                } 
            }
 
            return ServiceChannelFactory.BuildChannelFactory(this.Endpoint); 
        }
 
        void IDisposable.Dispose()
        {
            this.Close();
        } 

        void EnsureSecurityCredentialsManager(ServiceEndpoint endpoint) 
        { 
            DiagnosticUtility.DebugAssert(this.State == CommunicationState.Created || this.State == CommunicationState.Opening, "");
            if (endpoint.Behaviors.Find() == null) 
            {
                endpoint.Behaviors.Add(new ClientCredentials());
            }
        } 

        ClientCredentials EnsureCredentials(ServiceEndpoint endpoint) 
        { 
            DiagnosticUtility.DebugAssert(this.State == CommunicationState.Created || this.State == CommunicationState.Opening, "");
            ClientCredentials c = endpoint.Behaviors.Find(); 
            if (c == null)
            {
                c = new ClientCredentials();
                endpoint.Behaviors.Add(c); 
            }
            return c; 
        } 

        public T GetProperty() where T : class 
        {
            if (this.innerFactory != null)
            {
                return this.innerFactory.GetProperty(); 
            }
            else 
            { 
                return null;
            } 
        }

        internal bool HasDuplexOperations()
        { 
            OperationDescriptionCollection operations = this.Endpoint.Contract.Operations;
            for (int i = 0; i < operations.Count; i++) 
            { 
                OperationDescription operation = operations[i];
                if (operation.IsServerInitiated()) 
                {
                    return true;
                }
            } 

            return false; 
        } 

        protected void InitializeEndpoint(string configurationName, EndpointAddress address) 
        {
            this.serviceEndpoint = this.CreateDescription();

            if (address != null) 
            {
                this.Endpoint.Address = address; 
            } 

            ApplyConfiguration(configurationName); 

            this.configurationName = configurationName;
            EnsureSecurityCredentialsManager(this.serviceEndpoint);
        } 

        protected void InitializeEndpoint(ServiceEndpoint endpoint) 
        { 
            if (endpoint == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint");
            }

            this.serviceEndpoint = endpoint; 

            ApplyConfiguration(null); 
            EnsureSecurityCredentialsManager(this.serviceEndpoint); 
        }
 
        protected void InitializeEndpoint(Binding binding, EndpointAddress address)
        {
            this.serviceEndpoint = this.CreateDescription();
 
            if (binding != null)
            { 
                this.Endpoint.Binding = binding; 
            }
            if (address != null) 
            {
                this.Endpoint.Address = address;
            }
 
            ApplyConfiguration(null);
            EnsureSecurityCredentialsManager(this.serviceEndpoint); 
        } 

        protected override void OnOpened() 
        {
            // if a client credentials has been configured cache a readonly snapshot of it
            if (this.Endpoint != null)
            { 
                ClientCredentials credentials = this.Endpoint.Behaviors.Find();
                if (credentials != null) 
                { 
                    ClientCredentials credentialsCopy = credentials.Clone();
                    credentialsCopy.MakeReadOnly(); 
                    this.readOnlyClientCredentials = credentialsCopy;
                }
            }
            base.OnOpened(); 
        }
 
        protected override void OnAbort() 
        {
            if (this.innerFactory != null) 
            {
                this.innerFactory.Abort();
            }
        } 

        protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) 
        { 
            return new CloseAsyncResult(this.innerFactory, timeout, callback, state);
        } 

        protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
        {
            return new OpenAsyncResult(this.innerFactory, timeout, callback, state); 
        }
 
        protected override void OnClose(TimeSpan timeout) 
        {
            if(this.innerFactory != null) 
                this.innerFactory.Close(timeout);
        }

        protected override void OnEndClose(IAsyncResult result) 
        {
            CloseAsyncResult.End(result); 
        } 

        protected override void OnEndOpen(IAsyncResult result) 
        {
            OpenAsyncResult.End(result);
        }
 
        protected override void OnOpen(TimeSpan timeout)
        { 
            this.innerFactory.Open(timeout); 
        }
 
        protected override void OnOpening()
        {
            base.OnOpening();
 
            this.innerFactory = CreateFactory();
 
            if (this.innerFactory == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.InnerChannelFactoryWasNotSet)));
        } 

        class OpenAsyncResult : AsyncResult
        {
            ICommunicationObject communicationObject; 
            static AsyncCallback onOpenComplete = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnOpenComplete));
 
            public OpenAsyncResult(ICommunicationObject communicationObject, TimeSpan timeout, AsyncCallback callback, object state) 
                : base(callback, state)
            { 
                this.communicationObject = communicationObject;

                if (this.communicationObject == null)
                { 
                    this.Complete(true);
                    return; 
                } 

                IAsyncResult result = this.communicationObject.BeginOpen(timeout, onOpenComplete, this); 
                if (result.CompletedSynchronously)
                {
                    this.communicationObject.EndOpen(result);
                    this.Complete(true); 
                }
            } 
 
            static void OnOpenComplete(IAsyncResult result)
            { 
                if (result.CompletedSynchronously)
                    return;

                OpenAsyncResult thisPtr = (OpenAsyncResult)result.AsyncState; 
                Exception exception = null;
 
                try 
                {
                    thisPtr.communicationObject.EndOpen(result); 
                }
                catch (Exception e)
                {
                    if (DiagnosticUtility.IsFatal(e)) 
                        throw;
 
                    exception = e; 
                }
 
                thisPtr.Complete(false, exception);
            }

            public static void End(IAsyncResult result) 
            {
                AsyncResult.End(result); 
            } 
        }
 
        class CloseAsyncResult : AsyncResult
        {
            ICommunicationObject communicationObject;
            static AsyncCallback onCloseComplete = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnCloseComplete)); 

            public CloseAsyncResult(ICommunicationObject communicationObject, TimeSpan timeout, AsyncCallback callback, object state) 
                : base(callback, state) 
            {
                this.communicationObject = communicationObject; 

                if (this.communicationObject == null)
                {
                    this.Complete(true); 
                    return;
                } 
 
                IAsyncResult result = this.communicationObject.BeginClose(timeout, onCloseComplete, this);
 
                if (result.CompletedSynchronously)
                {
                    this.communicationObject.EndClose(result);
                    this.Complete(true); 
                }
            } 
 
            static void OnCloseComplete(IAsyncResult result)
            { 
                if (result.CompletedSynchronously)
                    return;

                CloseAsyncResult thisPtr = (CloseAsyncResult)result.AsyncState; 
                Exception exception = null;
 
                try 
                {
                    thisPtr.communicationObject.EndClose(result); 
                }
                catch (Exception e)
                {
                    if (DiagnosticUtility.IsFatal(e)) 
                        throw;
 
                    exception = e; 
                }
 
                thisPtr.Complete(false, exception);
            }

            public static void End(IAsyncResult result) 
            {
                AsyncResult.End(result); 
            } 
        }
    } 

    public class ChannelFactory : ChannelFactory, IChannelFactory
    {
        InstanceContext callbackInstance; 
        Type channelType;
        TypeLoader typeLoader; 
        Type callbackType; 

        //Overload for activation DuplexChannelFactory 
        protected ChannelFactory(Type channelType)
            : base()
        {
            if (channelType == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("channelType"); 
            } 

            if (!channelType.IsInterface) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxChannelFactoryTypeMustBeInterface)));
            }
 
            this.channelType = channelType;
        } 
 
        // TChannel provides ContractDescription
        public ChannelFactory() 
            : this(typeof(TChannel))
        {
            using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateBoundedActivity() : null)
            { 
                if (DiagnosticUtility.ShouldUseActivity)
                { 
                    ServiceModelActivity.Start(activity, SR.GetString(SR.ActivityConstructChannelFactory, typeof(TChannel).FullName), ActivityType.Construct); 
                }
                this.InitializeEndpoint((string)null, null); 
            }
        }

        // TChannel provides ContractDescription, attr/config [TChannel,name] provides Address,Binding 
        public ChannelFactory(string endpointConfigurationName)
            : this(endpointConfigurationName, null) 
        { 
        }
 
        // TChannel provides ContractDescription, attr/config [TChannel,name] provides Binding, provide Address explicitly
        public ChannelFactory(string endpointConfigurationName, EndpointAddress remoteAddress)
            : this(typeof(TChannel))
        { 
            using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateBoundedActivity() : null)
            { 
                if (DiagnosticUtility.ShouldUseActivity) 
                {
                    ServiceModelActivity.Start(activity, SR.GetString(SR.ActivityConstructChannelFactory, typeof(TChannel).FullName), ActivityType.Construct); 
                }
                if (endpointConfigurationName == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpointConfigurationName"); 
                }
 
                this.InitializeEndpoint(endpointConfigurationName, remoteAddress); 
            }
        } 

        // TChannel provides ContractDescription, attr/config [TChannel,name] provides Address,Binding
        public ChannelFactory(Binding binding)
            : this (binding, (EndpointAddress)null) 
        {
        } 
 
        public ChannelFactory(Binding binding, String remoteAddress)
            : this(binding, new EndpointAddress(remoteAddress)) 
        {
        }

        // TChannel provides ContractDescription, provide Address,Binding explicitly 
        public ChannelFactory(Binding binding, EndpointAddress remoteAddress)
            : this(typeof(TChannel)) 
        { 
            using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateBoundedActivity() : null)
            { 
                if (DiagnosticUtility.ShouldUseActivity)
                {
                    ServiceModelActivity.Start(activity, SR.GetString(SR.ActivityConstructChannelFactory, typeof(TChannel).FullName), ActivityType.Construct);
                } 
                if (binding == null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("binding"); 
                }
 
                this.InitializeEndpoint(binding, remoteAddress);
            }
        }
 
        // provide ContractDescription,Address,Binding explicitly
        public ChannelFactory(ServiceEndpoint endpoint) 
            : this(typeof(TChannel)) 
        {
            using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateBoundedActivity() : null) 
            {
                if (DiagnosticUtility.ShouldUseActivity)
                {
                    ServiceModelActivity.Start(activity, SR.GetString(SR.ActivityConstructChannelFactory, typeof(TChannel).FullName), ActivityType.Construct); 
                }
                if (endpoint == null) 
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint");
                } 

                this.InitializeEndpoint(endpoint);
            }
        } 

        internal InstanceContext CallbackInstance 
        { 
            get { return this.callbackInstance; }
            set { this.callbackInstance = value; } 
        }

        internal Type CallbackType
        { 
            get { return this.callbackType; }
            set { this.callbackType = value; } 
        } 

        internal ServiceChannelFactory ServiceChannelFactory 
        {
            get { return (ServiceChannelFactory)InnerFactory; }
        }
 
        internal TypeLoader TypeLoader
        { 
            get 
            {
                if (this.typeLoader == null) 
                    this.typeLoader = new TypeLoader();

                return this.typeLoader;
            } 
        }
 
        public TChannel CreateChannel(EndpointAddress address) 
        {
            if (address == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("address");
            }
 
            return CreateChannel(address, address.Uri);
        } 
 
        public virtual TChannel CreateChannel(EndpointAddress address, Uri via)
        { 
            bool traceOpenAndClose = this.TraceOpenAndClose;
            try
            {
                using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity && this.TraceOpenAndClose ? ServiceModelActivity.CreateBoundedActivity() : null) 
                {
                    if (DiagnosticUtility.ShouldUseActivity) 
                    { 
                        ServiceModelActivity.Start(activity, this.OpenActivityName, this.OpenActivityType);
                        // Turn open and close off for this open on contained objects. 
                        this.TraceOpenAndClose = false;
                    }
                    if (address == null)
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("address");
                    } 
 
                    if (this.HasDuplexOperations())
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCreateNonDuplexChannel1, this.Endpoint.Contract.Name)));
                    }

                    EnsureOpened(); 
                    return (TChannel)this.ServiceChannelFactory.CreateChannel(typeof(TChannel), address, via);
                } 
            } 
            finally
            { 
                this.TraceOpenAndClose = traceOpenAndClose;
            }
        }
 
        public TChannel CreateChannel()
        { 
            return CreateChannel(this.CreateEndpointAddress(this.Endpoint), null); 
        }
 
        internal override string CloseActivityName
        {
            get { return SR.GetString(SR.ActivityCloseChannelFactory, typeof(TChannel).FullName); }
        } 

        internal override string OpenActivityName 
        { 
            get { return SR.GetString(SR.ActivityOpenChannelFactory, typeof(TChannel).FullName); }
        } 

        internal override ActivityType OpenActivityType
        {
            get { return ActivityType.OpenClient; } 
        }
 
        internal UChannel CreateChannel(EndpointAddress address) 
        {
            EnsureOpened(); 
            return this.ServiceChannelFactory.CreateChannel(address);
        }

        internal UChannel CreateChannel(EndpointAddress address, Uri via) 
        {
            EnsureOpened(); 
            return this.ServiceChannelFactory.CreateChannel(address, via); 
        }
 
        internal bool CanCreateChannel()
        {
            EnsureOpened();
            return this.ServiceChannelFactory.CanCreateChannel(); 
        }
 
        protected override ServiceEndpoint CreateDescription() 
        {
            ContractDescription contractDescription = this.TypeLoader.LoadContractDescription(this.channelType); 

            ServiceEndpoint endpoint = new ServiceEndpoint(contractDescription);
            ReflectOnCallbackInstance(endpoint);
            this.TypeLoader.AddBehaviorsSFx(endpoint, channelType); 

            return endpoint; 
        } 

        void ReflectOnCallbackInstance(ServiceEndpoint endpoint) 
        {
            if (callbackType != null)
            {
                if (endpoint.Contract.CallbackContractType == null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SfxCallbackTypeCannotBeNull, endpoint.Contract.ContractType.FullName))); 
                } 

                this.TypeLoader.AddBehaviorsFromImplementationType(endpoint, callbackType); 
            }
            else if (this.CallbackInstance != null && this.CallbackInstance.UserObject != null)
            {
                if (endpoint.Contract.CallbackContractType == null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SfxCallbackTypeCannotBeNull, endpoint.Contract.ContractType.FullName))); 
                } 

                object implementation = this.CallbackInstance.UserObject; 
                Type implementationType = implementation.GetType();

                this.TypeLoader.AddBehaviorsFromImplementationType(endpoint, implementationType);
 
                IEndpointBehavior channelBehavior = implementation as IEndpointBehavior;
                if (channelBehavior != null) 
                { 
                    endpoint.Behaviors.Add(channelBehavior);
                } 
                IContractBehavior contractBehavior = implementation as IContractBehavior;
                if (contractBehavior != null)
                {
                    endpoint.Contract.Behaviors.Add(contractBehavior); 
                }
            } 
        } 

        //Static funtions to create channels 
        protected static TChannel CreateChannel(String endpointConfigurationName)
        {
            ChannelFactory channelFactory = new ChannelFactory(endpointConfigurationName);
 
            if (channelFactory.HasDuplexOperations())
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInvalidStaticOverloadCalledForDuplexChannelFactory1, channelFactory.channelType.Name))); 
            }
 
            TChannel channel = channelFactory.CreateChannel();
            SetFactoryToAutoClose(channel);
            return channel;
        } 

        public static TChannel CreateChannel(Binding binding, EndpointAddress endpointAddress) 
        { 
            ChannelFactory channelFactory = new ChannelFactory(binding, endpointAddress);
 
            if (channelFactory.HasDuplexOperations())
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInvalidStaticOverloadCalledForDuplexChannelFactory1, channelFactory.channelType.Name)));
            } 

            TChannel channel = channelFactory.CreateChannel(); 
            SetFactoryToAutoClose(channel); 
            return channel;
        } 

        public static TChannel CreateChannel(Binding binding, EndpointAddress endpointAddress, Uri via)
        {
            ChannelFactory channelFactory = new ChannelFactory(binding); 

            if (channelFactory.HasDuplexOperations()) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInvalidStaticOverloadCalledForDuplexChannelFactory1, channelFactory.channelType.Name)));
            } 

            TChannel channel = channelFactory.CreateChannel(endpointAddress, via);
            SetFactoryToAutoClose(channel);
            return channel; 
        }
 
        internal static void SetFactoryToAutoClose(TChannel channel) 
        {
            //Set the Channel to auto close its ChannelFactory. 
            ServiceChannel serviceChannel = ServiceChannelFactory.GetServiceChannel(channel);
            serviceChannel.CloseFactory = true;
        }
    } 
}

// 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