ContractInferenceHelper.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 / ContractInferenceHelper.cs / 1407647 / ContractInferenceHelper.cs

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

namespace System.ServiceModel.Activities 
{
    using System.Activities; 
    using System.Collections.Generic; 
    using System.Collections.ObjectModel;
    using System.Net.Security; 
    using System.Runtime;
    using System.ServiceModel.Activities.Description;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Description; 
    using System.Xml;
    using System.Xml.Linq; 
 
    static class ContractInferenceHelper
    { 
        static DataContractFormatAttribute dataContractFormatAttribute;
        static XmlSerializerFormatAttribute xmlSerializerFormatAttribute;
        static Type exceptionType;
        static Type faultExceptionType; 

        public static DataContractFormatAttribute DataContractFormatAttribute 
        { 
            get
            { 
                if (dataContractFormatAttribute == null)
                {
                    dataContractFormatAttribute = new DataContractFormatAttribute();
                } 
                return dataContractFormatAttribute;
            } 
        } 

        public static XmlSerializerFormatAttribute XmlSerializerFormatAttribute 
        {
            get
            {
                if (xmlSerializerFormatAttribute == null) 
                {
                    xmlSerializerFormatAttribute = new XmlSerializerFormatAttribute 
                    { 
                        SupportFaults = true
                    }; 
                }
                return xmlSerializerFormatAttribute;
            }
        } 

        public static Type ExceptionType 
        { 
            get
            { 
                if (exceptionType == null)
                {
                    exceptionType = typeof(Exception);
                } 
                return exceptionType;
            } 
        } 

        public static Type FaultExceptionType 
        {
            get
            {
                if (faultExceptionType == null) 
                {
                    faultExceptionType = typeof(FaultException<>); 
                } 
                return faultExceptionType;
            } 
        }

        public static void ProvideDefaultNamespace(ref XName serviceContractName)
        { 
            Fx.Assert(serviceContractName != null, "Argument cannot be null!");
 
            if (string.IsNullOrEmpty(serviceContractName.NamespaceName)) 
            {
                // If no namespace is given by the user, we provide default namespace. This is consistent with WCF. 
                serviceContractName = XName.Get(serviceContractName.LocalName, NamingHelper.DefaultNamespace);
            }
        }
 
        public static ContractDescription CreateContractFromOperation(XName serviceContractName, OperationDescription operation)
        { 
            Fx.Assert(serviceContractName != null, "serviceContractName cannot be null"); 
            ProvideDefaultNamespace(ref serviceContractName);
 
            ContractDescription contract = new ContractDescription(serviceContractName.LocalName, serviceContractName.NamespaceName)
            {
                // For inferred client side contracts, we do not set ContractType
 
                ConfigurationName = serviceContractName.LocalName,
                SessionMode = SessionMode.Allowed 
            }; 
            contract.Operations.Add(operation);
            return contract; 
        }

        public static ContractDescription CreateOutputChannelContractDescription(XName serviceContractName, ProtectionLevel? protectionLevel)
        { 
            Fx.Assert(serviceContractName != null, "cannot be null");
            Type channelType = typeof(IOutputChannel); 
 
            ProvideDefaultNamespace(ref serviceContractName);
 
            ContractDescription contract = new ContractDescription(serviceContractName.LocalName, serviceContractName.NamespaceName)
            {
                ContractType = channelType,
                ConfigurationName = serviceContractName.LocalName, 
                SessionMode = SessionMode.Allowed
            }; 
            OperationDescription operation = new OperationDescription("Send", contract); 
            MessageDescription message = new MessageDescription(MessageHeaders.WildcardAction, MessageDirection.Input);
            operation.Messages.Add(message); 

            if (protectionLevel.HasValue)
            {
                operation.ProtectionLevel = protectionLevel.Value; 
            }
 
            contract.Operations.Add(operation); 
            return contract;
        } 

        public static ContractDescription CreateRequestChannelContractDescription(XName serviceContractName, ProtectionLevel? protectionLevel)
        {
            Fx.Assert(serviceContractName != null, "cannot be null"); 
            Type channelType = typeof(IRequestChannel);
 
            ProvideDefaultNamespace(ref serviceContractName); 

            ContractDescription contract = new ContractDescription(serviceContractName.LocalName, serviceContractName.NamespaceName) 
            {
                ContractType = channelType,
                ConfigurationName = serviceContractName.LocalName,
                SessionMode = SessionMode.Allowed 
            };
            OperationDescription operation = new OperationDescription("Request", contract); 
            MessageDescription request = new MessageDescription(MessageHeaders.WildcardAction, MessageDirection.Input); 
            MessageDescription reply = new MessageDescription(MessageHeaders.WildcardAction, MessageDirection.Output);
            operation.Messages.Add(request); 
            operation.Messages.Add(reply);

            if (protectionLevel.HasValue)
            { 
                operation.ProtectionLevel = protectionLevel.Value;
            } 
 
            contract.Operations.Add(operation);
            return contract; 
        }

        public static void EnsureTransactionFlowOnContract(
            ref ServiceEndpoint serviceEndpoint, 
            XName serviceContractName,
            string operationName, 
            string action, 
            ProtectionLevel? protectionLevel)
        { 
            Fx.Assert(serviceEndpoint != null, "ServiceEndpoint cannot be null!");

            // Client side fully inferred contract always has null ContractType
            if (serviceEndpoint.Contract.ContractType == null) 
            {
                // If we are using the real contract, we only need to add TrancactionFlowAttribute to the operation 
                Fx.Assert(serviceEndpoint.Contract.Operations.Count == 1, "Client side contract should have exactly one operation!"); 

                serviceEndpoint.Contract.Operations[0].Behaviors.Add(new TransactionFlowAttribute(TransactionFlowOption.Allowed)); 
            }
            else
            {
                // Replace the original fake contract with a fake contract tailored for transaction 

                ContractDescription contract = null; 
                OperationDescription operation = null; 
                MessageDescription request = null;
                MessageDescription reply = null; 

                Type channelType = typeof(IRequestChannel);

                // We need to create a contract description with the real service contract name 
                // and operation name and actions and with the TransactionFlow operation behavior
                // because the TransactionChannelFactory has a dictionary of "Directional Action" to 
                // transaction flow value that it uses to decide whether or not to include the 
                // transaction header in the message.
                Fx.Assert(serviceContractName != null, "Argument serviceContractName cannot be null!"); 
                Fx.Assert(operationName != null, "Argument operationName cannot be null!");

                ProvideDefaultNamespace(ref serviceContractName);
 
                contract = new ContractDescription(serviceContractName.LocalName, serviceContractName.NamespaceName)
                { 
                    ContractType = channelType, 
                    SessionMode = SessionMode.Allowed
                }; 
                operation = new OperationDescription(operationName, contract);
                operation.Behaviors.Add(new TransactionFlowAttribute(TransactionFlowOption.Allowed));

                string requestAction = null; 
                string replyAction = null;
                if (String.IsNullOrEmpty(action)) 
                { 
                    // Construct the action.
                    requestAction = NamingHelper.GetMessageAction(operation, false); 
                    replyAction = NamingHelper.GetMessageAction(operation, true);
                }
                else
                { 
                    requestAction = action;
                    replyAction = action + TypeLoader.ResponseSuffix; 
                } 

                request = new MessageDescription(requestAction, MessageDirection.Input); 
                reply = new MessageDescription(replyAction, MessageDirection.Output);

                operation.Messages.Add(request);
                operation.Messages.Add(reply); 

                if (protectionLevel.HasValue) 
                { 
                    operation.ProtectionLevel = protectionLevel.Value;
                } 

                contract.Operations.Add(operation);

                // We need to replace the ServiceEndpoint because ServiceEndpoint.Contract does not have a public setter 
                Uri listenUri = serviceEndpoint.ListenUri;
                serviceEndpoint = new ServiceEndpoint(contract) 
                { 
                    Binding = serviceEndpoint.Binding,
                    Address = serviceEndpoint.Address, 
                    Name = serviceEndpoint.Name,
                };
                if (listenUri != null)
                { 
                    serviceEndpoint.ListenUri = listenUri;
                } 
            } 
        }
 
        public static OperationDescription CreateOneWayOperationDescription(Send send)
        {
            Fx.Assert(send != null, "Argument cannot be null!");
            return CreateOperationDescriptionCore(send, null); 
        }
 
        public static OperationDescription CreateTwoWayOperationDescription(Send send, ReceiveReply receiveReply) 
        {
            Fx.Assert(send != null && receiveReply != null, "Arguments cannot be null!"); 
            return CreateOperationDescriptionCore(send, receiveReply);
        }

        static OperationDescription CreateOperationDescriptionCore(Send send, ReceiveReply receiveReply) 
        {
            XName contractXName = send.ServiceContractName; 
            ProvideDefaultNamespace(ref contractXName); 

            // Infer Name, Namespace, ConfigurationName 
            ContractDescription contract = new ContractDescription(contractXName.LocalName, contractXName.NamespaceName);
            contract.ConfigurationName = send.EndpointConfigurationName;

            OperationDescription operation = new OperationDescription(NamingHelper.XmlName(send.OperationName), contract); 
            if (send.ProtectionLevel.HasValue)
            { 
                operation.ProtectionLevel = send.ProtectionLevel.Value; 
            }
 
            AddKnownTypesToOperation(operation, send.KnownTypes);

            // Infer In-Message
            send.InternalContent.InferMessageDescription(operation, send, MessageDirection.Input); 

            // Infer Out-Message 
            if (receiveReply != null) 
            {
                receiveReply.InternalContent.InferMessageDescription(operation, receiveReply, MessageDirection.Output); 
            }

            PostProcessOperation(operation);
            AddSerializerProvider(operation, send.SerializerOption); 

            contract.Operations.Add(operation); 
 
            return operation;
        } 

        // Create server side OperationDescription
        public static OperationDescription CreateOperationDescription(Receive receive, ContractDescription contract)
        { 
            OperationDescription operation = new OperationDescription(NamingHelper.XmlName(receive.OperationName), contract);
 
            if (receive.ProtectionLevel.HasValue) 
            {
                operation.ProtectionLevel = receive.ProtectionLevel.Value; 
            }

            // Infer In-Message
            receive.InternalContent.InferMessageDescription(operation, receive, MessageDirection.Input); 

            // Infer Out-Message 
            if (receive.HasReply) 
            {
                // At this point, we already know all the following SendReplies are equivalent 
                SendReply sendReply = receive.FollowingReplies[0];
                sendReply.InternalContent.InferMessageDescription(operation, sendReply, MessageDirection.Output);
            }
            else if (receive.HasFault) 
            {
                // We infer Receive-SendFault pair as a two-way operation with void return value 
                CheckForDisposableParameters(operation, Constants.EmptyTypeArray); 
                AddOutputMessage(operation, null, Constants.EmptyStringArray, Constants.EmptyTypeArray);
            } 

            PostProcessOperation(operation);

            // Behaviors 
            AddSerializerProvider(operation, receive.SerializerOption);
            AddWorkflowOperationBehaviors(operation, receive.OperationBookmarkName, receive.CanCreateInstance); 
 
            if (receive.InternalReceive.AdditionalData.IsInsideTransactedReceiveScope)
            { 
                operation.IsInsideTransactedReceiveScope = true;
                EnableTransactionBehavior(operation);
                if (receive.InternalReceive.AdditionalData.IsFirstReceiveOfTransactedReceiveScopeTree)
                { 
                    operation.IsFirstReceiveOfTransactedReceiveScopeTree = true;
                } 
            } 

            return operation; 
        }

        public static void AddInputMessage(OperationDescription operation, string overridingAction, Type type, SerializerOption serializerOption)
        { 
            Fx.Assert(operation.Messages.Count == 0, "Operation already has input message");
 
            bool isResponse = false; 
            MessageDescription message = MessageBuilder.CreateMessageDescription(
                operation, isResponse, MessageDirection.Input, overridingAction, type, serializerOption); 

            operation.Messages.Add(message);
        }
 
        public static void AddInputMessage(OperationDescription operation, string overridingAction,
            string[] argumentNames, Type[] argumentTypes) 
        { 
            Fx.Assert(operation.Messages.Count == 0, "Operation already has input message");
 
            bool isResponse = false;
            MessageDescription message = MessageBuilder.CreateMessageDescription(
                operation, isResponse, MessageDirection.Input, overridingAction, argumentNames, argumentTypes);
 
            operation.Messages.Add(message);
        } 
 
        public static void AddOutputMessage(OperationDescription operation, string overridingAction, Type type, SerializerOption serializerOption)
        { 
            Fx.Assert(operation.Messages.Count > 0, "Operation does not have input message");
            Fx.Assert(operation.Messages.Count < 2, "Operation already has output message");

            bool isResponse = true; 
            MessageDescription message = MessageBuilder.CreateMessageDescription(
                operation, isResponse, MessageDirection.Output, overridingAction, type, serializerOption); 
 
            operation.Messages.Add(message);
        } 

        public static void AddOutputMessage(OperationDescription operation, string overridingAction,
            string[] argumentNames, Type[] argumentTypes)
        { 
            Fx.Assert(operation.Messages.Count > 0, "Operation does not have input message");
            Fx.Assert(operation.Messages.Count < 2, "Operation already has output message"); 
 
            bool isResponse = true;
            MessageDescription message = MessageBuilder.CreateMessageDescription( 
                operation, isResponse, MessageDirection.Output, overridingAction, argumentNames, argumentTypes);

            operation.Messages.Add(message);
        } 

        static void AddKnownTypesToOperation(OperationDescription operation, Collection knownTypes) 
        { 
            if (knownTypes != null)
            { 
                foreach (Type knownType in knownTypes)
                {
                    operation.KnownTypes.Add(knownType);
                } 
            }
        } 
 
        public static void CheckForDisposableParameters(OperationDescription operation, Type type)
        { 
            if (type == null)
            {
                 operation.HasNoDisposableParameters = true;
            } 
            else
            { 
                operation.HasNoDisposableParameters = !ServiceReflector.IsParameterDisposable(type); 
            }
        } 

        public static void CheckForDisposableParameters(OperationDescription operation, Type[] types)
        {
            Fx.Assert(types != null, "Argument cannot be null!"); 

            operation.HasNoDisposableParameters = true; 
            foreach (Type type in types) 
            {
                if (ServiceReflector.IsParameterDisposable(type)) 
                {
                    operation.HasNoDisposableParameters = false;
                    break;
                } 
            }
        } 
 
        static void EnableTransactionBehavior(OperationDescription operationDescription)
        { 
            Fx.Assert(operationDescription != null, "OperationDescription is null");

            OperationBehaviorAttribute attribute = operationDescription.Behaviors.Find();
            if (attribute != null) 
            {
                attribute.TransactionScopeRequired = true; 
                attribute.TransactionAutoComplete = false; 
            }
            else 
            {
                OperationBehaviorAttribute attr = new OperationBehaviorAttribute
                {
                    TransactionAutoComplete = false, 
                    TransactionScopeRequired = true
                }; 
                operationDescription.Behaviors.Add(attr); 
            }
            TransactionFlowAttribute transactionFlowAttribute = operationDescription.Behaviors.Find(); 
            if (transactionFlowAttribute != null)
            {
                if(transactionFlowAttribute.Transactions != TransactionFlowOption.Allowed)
                { 
                    throw FxTrace.Exception.AsError(new InvalidOperationException(SR.ContractInferenceValidationForTransactionFlowBehavior));
                } 
            } 
            else
            { 
                if (!operationDescription.IsOneWay)
                {
                    operationDescription.Behaviors.Add(new TransactionFlowAttribute(TransactionFlowOption.Allowed));
                } 
            }
        } 
 
        static void PostProcessOperation(OperationDescription operation)
        { 
            MessageBuilder.ClearWrapperNames(operation);
        }

        static void AddSerializerProvider(OperationDescription operation, SerializerOption serializerOption) 
        {
            switch (serializerOption) 
            { 
                case SerializerOption.DataContractSerializer:
                    AddDataContractSerializerFormat(operation); 
                    break;
                case SerializerOption.XmlSerializer:
                    AddXmlSerializerFormat(operation);
                    break; 
            }
        } 
 
        static void AddDataContractSerializerFormat(OperationDescription operation)
        { 
            if (operation.Behaviors.Find() != null)
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.OperationHasSerializerBehavior(
                    operation.Name, operation.DeclaringContract.Name, typeof(DataContractSerializerOperationBehavior)))); 
            }
            operation.Behaviors.Add(new DataContractSerializerOperationBehavior(operation, DataContractFormatAttribute)); 
            if (!operation.Behaviors.Contains(typeof(DataContractSerializerOperationGenerator))) 
            {
                operation.Behaviors.Add(new DataContractSerializerOperationGenerator()); 
            }
        }

        static void AddXmlSerializerFormat(OperationDescription operation) 
        {
            if (operation.Behaviors.Find() != null) 
            { 
                throw FxTrace.Exception.AsError(new InvalidOperationException(
                    SR.OperationHasSerializerBehavior(operation.Name, operation.DeclaringContract.Name, typeof(XmlSerializerOperationBehavior)))); 
            }
            operation.Behaviors.Add(new XmlSerializerOperationBehavior(operation, XmlSerializerFormatAttribute));
            if (!operation.Behaviors.Contains(typeof(XmlSerializerOperationGenerator)))
            { 
                operation.Behaviors.Add(new XmlSerializerOperationGenerator(new XmlSerializerImportOptions()));
            } 
        } 

        static void AddWorkflowOperationBehaviors(OperationDescription operation, string bookmarkName, bool canCreateInstance) 
        {
            KeyedByTypeCollection behaviors = operation.Behaviors;
            WorkflowOperationBehavior workflowOperationBehavior = behaviors.Find();
            if (workflowOperationBehavior == null) 
            {
                behaviors.Add(new WorkflowOperationBehavior(new Bookmark(bookmarkName), canCreateInstance)); 
            } 
            else
            { 
                workflowOperationBehavior.CanCreateInstance = workflowOperationBehavior.CanCreateInstance || canCreateInstance;
            }
        }
 
        public static void CorrectOutMessageForOperation(Receive receive, OperationDescription operation)
        { 
            // Remove the original outMessage 
            Fx.Assert(operation.Messages.Count == 2, "OperationDescription must be two-way for CorrectOutMessageForOperation to be invoked!");
            operation.Messages.RemoveAt(1); 

            SendReply sendReply = receive.FollowingReplies[0];
            sendReply.InternalContent.InferMessageDescription(operation, sendReply, MessageDirection.Output);
 
            ContractInferenceHelper.PostProcessOperation(operation);
        } 
 
        public static void UpdateIsOneWayFlag(Receive receive, OperationDescription operation)
        { 
            // Set InternalReceiveMessage.IsOneWay to false for two-way operations
            if (!operation.IsOneWay)
            {
                receive.SetIsOneWay(false); 
            }
        } 
 
        public static void AddFaultDescription(Receive activity, OperationDescription operation)
        { 
            if (activity.HasFault)
            {
                foreach (SendReply sendFault in activity.FollowingFaults)
                { 
                    string action = null;
                    Type type = null; 
 
                    action = sendFault.Action;
 
                    SendMessageContent sendReply = sendFault.InternalContent as SendMessageContent;
                    if (sendReply != null)
                    {
                        type = sendReply.InternalDeclaredMessageType; 
                    }
                    else 
                    { 
                        SendParametersContent sendReplyParameters = sendFault.InternalContent as SendParametersContent;
                        if (sendReplyParameters != null) 
                        {
                            type = sendReplyParameters.ArgumentTypes[0];  // Exception should be the only parameter in SendFault
                        }
                    } 

                    Fx.Assert(type != null, "Exception type cannot be null!"); 
                    if (type.IsGenericType && type.GetGenericTypeDefinition() == FaultExceptionType) 
                    {
                        Type faultType = type.GetGenericArguments()[0]; 
                        bool exists = false;

                        // We expect the number of fault types to be small, so we use iterative comparison
                        foreach (FaultDescription faultDescription in operation.Faults) 
                        {
                            if (faultDescription.DetailType == faultType) 
                            { 
                                if (faultDescription.Action != action)
                                { 
                                    throw FxTrace.Exception.AsError(new ValidationException(SR.SendRepliesHaveSameFaultTypeDifferentAction));
                                }
                                else
                                { 
                                    exists = true;
                                    break; 
                                } 
                            }
                        } 

                        if (!exists)
                        {
                            FaultDescription faultDescription = MessageBuilder.CreateFaultDescription(operation, faultType, action); 
                            operation.Faults.Add(faultDescription);
                        } 
                    } 
                }
            } 
        }

        public static void AddKnownTypesToOperation(Receive receive, OperationDescription operation)
        { 
            Collection knownTypes = receive.InternalKnownTypes;
 
            if (knownTypes != null) 
            {
                foreach (Type knownType in knownTypes) 
                {
                    // We expect the number of known types to be small, so we use iterative comparison
                    if (!operation.KnownTypes.Contains(knownType))
                    { 
                        operation.KnownTypes.Add(knownType);
                    } 
                } 
            }
        } 

        public static void AddReceiveToFormatterBehavior(Receive receive, OperationDescription operation)
        {
            Fx.Assert(receive != null && operation != null, "Argument cannot be null!"); 

            KeyedByTypeCollection behaviors = operation.Behaviors; 
            WorkflowFormatterBehavior formatterBehavior = behaviors.Find(); 
            if (formatterBehavior == null)
            { 
                formatterBehavior = new WorkflowFormatterBehavior();
                behaviors.Add(formatterBehavior);
            }
 
            formatterBehavior.Receives.Add(receive);
        } 
 
        public static CorrelationQuery CreateServerCorrelationQuery(MessageQuerySet select, Collection correlationInitializers,
            OperationDescription operation, bool isResponse) 
        {
            Fx.Assert(operation != null, "Argument cannot be null!");

            CorrelationQuery correlationQuery = CreateCorrelationQueryCore(select, correlationInitializers); 

            if (correlationQuery != null) 
            { 
                string action = !isResponse ? operation.Messages[0].Action : operation.Messages[1].Action;
                correlationQuery.Where = new CorrelationActionMessageFilter { Action = action }; 
            }

            return correlationQuery;
        } 

        // this method generates the correlationQuery for client side send and receiveReply 
        public static Collection CreateClientCorrelationQueries(MessageQuerySet select, Collection correlationInitializers, 
            string overridingAction, XName serviceContractName, string operationName, bool isResponse)
        { 
            Fx.Assert(serviceContractName != null && operationName != null, "Argument cannot be null!");

            Collection queryCollection = new Collection();
            CorrelationQuery correlationQuery = CreateCorrelationQueryCore(select, correlationInitializers); 

            if (correlationQuery != null) 
            { 
                if (overridingAction != null)
                { 
                    correlationQuery.Where = new CorrelationActionMessageFilter { Action = overridingAction };
                }
                else
                { 
                    ProvideDefaultNamespace(ref serviceContractName);
                    string defaultAction = NamingHelper.GetMessageAction(new XmlQualifiedName(serviceContractName.LocalName, serviceContractName.NamespaceName), 
                        operationName, null, isResponse); 

                    correlationQuery.Where = new CorrelationActionMessageFilter { Action = defaultAction }; 
                }

                queryCollection.Add(correlationQuery);
 
                if (isResponse)
                { 
                    // we need an additional query with empty action to support soap1.1 reply cases 
                    CorrelationQuery noActionQuery = correlationQuery.Clone();
                    noActionQuery.Where = new CorrelationActionMessageFilter { Action = String.Empty }; 
                    queryCollection.Add(noActionQuery);
                }
            }
 
            return queryCollection;
        } 
 
        static CorrelationQuery CreateCorrelationQueryCore(MessageQuerySet select, Collection correlationInitializers)
        { 
            CorrelationQuery correlationQuery = null;

            if (select != null)
            { 
                Fx.Assert(select.Count != 0, "Empty MessageQuerySet is not allowed!");
 
                correlationQuery = new CorrelationQuery 
                {
                    Select = select 
                };
            }

            if (correlationInitializers != null && correlationInitializers.Count > 0) 
            {
                foreach (CorrelationInitializer correlation in correlationInitializers) 
                { 
                    QueryCorrelationInitializer queryCorrelation = correlation as QueryCorrelationInitializer;
                    if (queryCorrelation != null) 
                    {
                        Fx.Assert(queryCorrelation.MessageQuerySet.Count != 0, "Empty MessageQuerySet is not allowed!");

                        correlationQuery = correlationQuery ?? new CorrelationQuery(); 
                        correlationQuery.SelectAdditional.Add(queryCorrelation.MessageQuerySet);
                    } 
                } 
            }
 
            return correlationQuery;
        }
    }
} 

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