Send.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.ServiceModel.Activities / System / ServiceModel / Activities / Send.cs / 1407647 / Send.cs

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

namespace System.ServiceModel.Activities 
{
    using System.Activities; 
    using System.Activities.Expressions; 
    using System.Activities.Statements;
    using System.Collections.Generic; 
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Net.Security;
    using System.Runtime; 
    using System.Security.Principal;
    using System.ServiceModel.Channels; 
    using System.ServiceModel.Description; 
    using System.ServiceModel.Dispatcher;
    using System.ServiceModel.XamlIntegration; 
    using System.Windows.Markup;
    using System.Xml.Linq;

    [ContentProperty("Content")] 
    public sealed class Send : Activity
    { 
        ToRequest requestFormatter; 
        InternalSendMessage internalSend;
        Collection knownTypes; 

        Collection correlationInitializers;

        bool isOneWay; 
        IClientMessageFormatter lazyFormatter;
        IList lazyCorrelationQueries; 
 
        bool? channelCacheEnabled;
 
        public Send()
        {
            this.isOneWay = true; // ReceiveReply if defined by user, will set this to false
            this.TokenImpersonationLevel = TokenImpersonationLevel.Identification; 
            base.Implementation = () =>
            { 
                // if CacheMetadata isn't called, bail early 
                if (this.internalSend == null)
                { 
                    return null;
                }

                if (this.requestFormatter == null) 
                {
                    return this.internalSend; 
                } 
                else
                { 
                    Variable request = new Variable { Name = "RequestMessage" };
                    this.requestFormatter.Message = new OutArgument(request);
                    this.requestFormatter.Send = this;
                    this.internalSend.Message = new InArgument(request); 

                    return new NoPersistScope 
                    { 
                        Body = new Sequence
                        { 
                            Variables = { request },
                            Activities =
                            {
                                this.requestFormatter, 
                                this.internalSend,
                            } 
                        } 
                    };
                } 
            };
        }

        // the content to send (either message or parameters-based) declared by the user 
        [DefaultValue(null)]
        public SendContent Content 
        { 
            get;
            set; 
        }

        // Internally, we should always use InternalContent since this property may have default content that we added
        internal SendContent InternalContent 
        {
            get 
            { 
                return this.Content ?? SendContent.DefaultSendContent;
            } 
        }

        // Additional correlations allow situations where a "session" involves multiple
        // messages between two workflow instances. 
        public Collection CorrelationInitializers
        { 
            get 
            {
                if (this.correlationInitializers == null) 
                {
                    this.correlationInitializers = new Collection();
                }
                return this.correlationInitializers; 
            }
        } 
 
        // Allows the action for the message to be specified by the user/designer.
        // If not set, the value is constructed from the Name of the activity. 
        // If specified on the Send side of a message, the Receive side needs to have the same value in order
        // for the message to be delivered correctly.
        [DefaultValue(null)]
        public string Action 
        {
            get; 
            set; 
        }
 
        [DefaultValue(null)]
        public InArgument CorrelatesWith
        {
            get; 
            set;
        } 
 
        // Specifies the endpoint of the service we are sending to. If not specified, it must come
        // from the configuration file. 
        [DefaultValue(null)]
        public Endpoint Endpoint
        {
            get; 
            set;
        } 
 
        // This is used to load the client Endpoint from configuration. This should be mutually exclusive
        // with the Endpoint property. 
        // optional defaults to ServiceContractName.LocalName
        [DefaultValue(null)]
        public string EndpointConfigurationName
        { 
            get;
            set; 
        } 

        // Allows the address portion of the endpoint to be overridden at runtime by the 
        // workflow instance.
        [DefaultValue(null)]
        public InArgument EndpointAddress
        { 
            get;
            set; 
        } 

        // Do we need this? 
        public Collection KnownTypes
        {
            get
            { 
                if (this.knownTypes == null)
                { 
                    this.knownTypes = new Collection(); 
                }
                return this.knownTypes; 
            }
        }

        // this will be used to construct the default value for Action if the Action property is 
        // not specifically set.
        // There is validation to make sure either this or Action has a value. 
        [DefaultValue(null)] 
        public string OperationName
        { 
            get;
            set;
        }
 
        // The protection level for the message.
        // If ValueType or Value.Expression.Type is MessageContract, the MessageContract definition may have additional settings. 
        // Default if this is not specified is Sign. 
        [DefaultValue(null)]
        public ProtectionLevel? ProtectionLevel 
        {
            get;
            set;
        } 

        // Maybe an enum to limit possibilities 
        // I am still a little fuzzy on this property. 
        [DefaultValue(SerializerOption.DataContractSerializer)]
        public SerializerOption SerializerOption 
        {
            get;
            set;
        } 

        // The service contract name. This allows the same workflow instance to implement multiple 
        // servce "contracts". If not specified and this is the first Receive* activity in the 
        // workflow, contract inference uses this activity's Name as the service contract name.
        [DefaultValue(null)] 
        [TypeConverter(typeof(ServiceXNameTypeConverter))]
        public XName ServiceContractName
        {
            get; 
            set;
        } 
        // The token impersonation level that is allowed for the receiver of the message. 
        [DefaultValue(TokenImpersonationLevel.Identification)]
        public TokenImpersonationLevel TokenImpersonationLevel 
        {
            get;
            set;
        } 

        internal bool ChannelCacheEnabled 
        { 
            get
            { 
                Fx.Assert(this.channelCacheEnabled.HasValue, "The value of channelCacheEnabled must be initialized!");
                return this.channelCacheEnabled.Value;
            }
        } 

        internal bool OperationUsesMessageContract 
        { 
            get;
            set; 
        }

        internal OperationDescription OperationDescription
        { 
            get;
            set; 
        } 

        protected override void CacheMetadata(ActivityMetadata metadata) 
        {
            if (string.IsNullOrEmpty(this.OperationName))
            {
                metadata.AddValidationError(SR.MissingOperationName(this.DisplayName)); 
            }
            if (this.ServiceContractName == null) 
            { 
                string errorOperationName = ContractValidationHelper.GetErrorMessageOperationName(this.OperationName);
                metadata.AddValidationError(SR.MissingServiceContractName(this.DisplayName, errorOperationName)); 
            }

            if (this.Endpoint == null)
            { 
                if (string.IsNullOrEmpty(this.EndpointConfigurationName))
                { 
                    metadata.AddValidationError(SR.EndpointNotSet(this.DisplayName, this.OperationName)); 
                }
            } 
            else
            {
                if(!string.IsNullOrEmpty(this.EndpointConfigurationName))
                { 
                    metadata.AddValidationError(SR.EndpointIncorrectlySet(this.DisplayName, this.OperationName));
                } 
                if (this.Endpoint.Binding == null) 
                {
                    metadata.AddValidationError(SR.MissingBindingInEndpoint(this.Endpoint.Name, this.ServiceContractName)); 
                }
            }

            // validate Correlation Initializers 
            MessagingActivityHelper.ValidateCorrelationInitializer(metadata, this.correlationInitializers, false, this.DisplayName, this.OperationName);
 
            // Add runtime arguments 
            MessagingActivityHelper.AddRuntimeArgument(this.CorrelatesWith, "CorrelatesWith", Constants.CorrelationHandleType, ArgumentDirection.In, metadata);
            MessagingActivityHelper.AddRuntimeArgument(this.EndpointAddress, "EndpointAddress", Constants.UriType, ArgumentDirection.In, metadata); 

            // Validate Content
            this.InternalContent.CacheMetadata(metadata, this, this.OperationName);
 
            if (this.correlationInitializers != null)
            { 
                for (int i = 0; i < this.correlationInitializers.Count; i++) 
                {
                    CorrelationInitializer initializer = this.correlationInitializers[i]; 
                    initializer.ArgumentName = Constants.Parameter + i;
                    RuntimeArgument initializerArgument = new RuntimeArgument(initializer.ArgumentName, Constants.CorrelationHandleType, ArgumentDirection.In);
                    metadata.Bind(initializer.CorrelationHandle, initializerArgument);
                    metadata.AddArgument(initializerArgument); 
                }
            } 
 
            if (!metadata.HasViolations)
            { 
                if (this.InternalContent is SendMessageContent
                    && MessageBuilder.IsMessageContract(((SendMessageContent)this.InternalContent).InternalDeclaredMessageType))
                {
                    this.OperationUsesMessageContract = true; 
                }
 
                this.internalSend = CreateInternalSend(); 
                this.InternalContent.ConfigureInternalSend(this.internalSend, out this.requestFormatter);
 
                if (this.requestFormatter != null && this.lazyFormatter != null)
                {
                    this.requestFormatter.Formatter = this.lazyFormatter;
                } 
            }
            else 
            { 
                this.internalSend = null;
                this.requestFormatter = null; 
            }
        }

        InternalSendMessage CreateInternalSend() 
        {
            InternalSendMessage result = new InternalSendMessage 
            { 
                OperationName = this.OperationName,
                CorrelatesWith = new InArgument(new ArgumentValue { ArgumentName = "CorrelatesWith" }), 
                Endpoint = this.Endpoint,
                EndpointConfigurationName = this.EndpointConfigurationName,
                IsOneWay = this.isOneWay,
                IsSendReply = false, 
                TokenImpersonationLevel = this.TokenImpersonationLevel,
                ServiceContractName = this.ServiceContractName, 
                Action = this.Action, 
                Parent = this
            }; 

            if (this.correlationInitializers != null)
            {
                foreach (CorrelationInitializer correlation in this.correlationInitializers) 
                {
                    result.CorrelationInitializers.Add(correlation.Clone()); 
                } 

                Collection internalCorrelationQueryCollection = ContractInferenceHelper.CreateClientCorrelationQueries(null, this.correlationInitializers, 
                        this.Action, this.ServiceContractName, this.OperationName, false);
                Fx.Assert(internalCorrelationQueryCollection.Count <= 1, "Querycollection for send cannot have more than one correlation query");
                if (internalCorrelationQueryCollection.Count == 1)
                { 
                    result.CorrelationQuery = internalCorrelationQueryCollection[0];
                } 
            } 

            if (this.EndpointAddress != null) 
            {
                result.EndpointAddress = new InArgument(context => ((InArgument)this.EndpointAddress).Get(context));
            }
 
            if (this.lazyCorrelationQueries != null)
            { 
                foreach (CorrelationQuery correlationQuery in this.lazyCorrelationQueries) 
                {
                    result.ReplyCorrelationQueries.Add(correlationQuery); 
                }
            }

            return result; 
        }
 
        // Acccessed by ReceiveReply.CreateBody to set OneWay to false 
        internal void SetIsOneWay(bool value)
        { 
            this.isOneWay = value;
            if (this.internalSend != null)
            {
                this.internalSend.IsOneWay = this.isOneWay; 
            }
        } 
 
        internal MessageVersion GetMessageVersion()
        { 
            return this.internalSend.GetMessageVersion();
        }

        internal void SetFormatter(IClientMessageFormatter formatter) 
        {
            if (this.requestFormatter != null) 
            { 
                this.requestFormatter.Formatter = formatter;
            } 
            else
            {
                // we save the formatter and set the requestFormatter.Formatter later
                this.lazyFormatter = formatter; 
            }
        } 
 
        internal void SetReplyCorrelationQuery(CorrelationQuery replyQuery)
        { 
            Fx.Assert(replyQuery != null, "replyQuery cannot be null!");

            if (this.internalSend != null && !this.internalSend.ReplyCorrelationQueries.Contains(replyQuery))
            { 
                this.internalSend.ReplyCorrelationQueries.Add(replyQuery);
            } 
            else 
            {
                // we save the CorrelationQuery and add it to InternalSendMessage later 
                if (this.lazyCorrelationQueries == null)
                {
                    this.lazyCorrelationQueries = new List();
                } 
                this.lazyCorrelationQueries.Add(replyQuery);
            } 
        } 

        internal void InitializeChannelCacheEnabledSetting(ActivityContext context) 
        {
            if (!this.channelCacheEnabled.HasValue)
            {
                SendMessageChannelCache channelCacheExtension = context.GetExtension(); 
                Fx.Assert(channelCacheExtension != null, "channelCacheExtension must exist!");
 
                InitializeChannelCacheEnabledSetting(channelCacheExtension); 
            }
        } 

        internal void InitializeChannelCacheEnabledSetting(SendMessageChannelCache channelCacheExtension)
        {
            Fx.Assert(channelCacheExtension != null, "channelCacheExtension cannot be null!"); 

            ChannelCacheSettings factorySettings = channelCacheExtension.FactorySettings; 
            Fx.Assert(factorySettings != null, "FactorySettings cannot be null!"); 

            bool enabled; 

            if (factorySettings.IdleTimeout == TimeSpan.Zero || factorySettings.LeaseTimeout == TimeSpan.Zero || factorySettings.MaxItemsInCache == 0)
            {
                enabled = false; 
            }
            else 
            { 
                enabled = true;
            } 

            if (!this.channelCacheEnabled.HasValue)
            {
                this.channelCacheEnabled = enabled; 
            }
            else 
            { 
                Fx.Assert(this.channelCacheEnabled.Value == enabled, "Once ChannelCacheEnabled is set, it cannot be changed!");
            } 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

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