private void BuildCallbackMap()
        {
            Type t = GetType();

            m_dispatchMap = new Dictionary <BrokerMethodAttribute, MethodInfo>();
            MethodInfo[] methodInfoArray = t.GetMethods(BindingFlags.Public | BindingFlags.Instance);
            foreach (MethodInfo methodInfo in methodInfoArray)
            {
                object[] attributes = methodInfo.GetCustomAttributes(typeof(BrokerMethodAttribute), true);
                foreach (BrokerMethodAttribute statefulTransition in attributes)
                {
                    BrokerMethodAttribute statelessTransition =
                        new BrokerMethodAttribute(statefulTransition.Contract, statefulTransition.MessageType);
                    if (m_dispatchMap.ContainsKey(statefulTransition) ||
                        m_dispatchMap.ContainsKey(statelessTransition))
                    {
                        string exceptionMessage = "Method '" + methodInfo.Name +
                                                  "' redefines a handler for message type '" + statefulTransition.MessageType + "'";
                        if (statefulTransition.State != -1)
                        {
                            exceptionMessage += " in state " + statefulTransition.State;
                        }

                        throw new NotSupportedException(exceptionMessage);
                    }

                    m_dispatchMap[statefulTransition] = methodInfo;
                }
            }
        }
        public override bool Equals(object obj)
        {
            if (obj.GetType() != typeof(BrokerMethodAttribute))
            {
                return(false);
            }
            BrokerMethodAttribute other = (BrokerMethodAttribute)obj;

            return(m_state == other.m_state &&
                   m_contract == other.m_contract &&
                   m_messageType == other.m_messageType);
        }
        /// <summary>
        /// This method provides a default implementation for dispatching messages
        /// to the appropriate broker methods as specified in the derived class. The user
        /// may overrride this method if attributed methods are not desired.
        /// </summary>
        /// <param name="message">The message received by the service</param>
        /// <param name="connection">Connection which was used for doing the RECEIVE</param>
        /// <param name="transaction">Transaction which was used for doing the RECEIVE</param>
        /// <exception cref="NotImplementedException">Thrown if there is no broker method to
        /// handle the current event</exception>
        public virtual void DispatchMessage(
            Message message,
            SqlConnection connection,
            SqlTransaction transaction)
        {
            if (message.Type == Message.EchoType && message.ContractName == EchoContractName)
            {
                EchoHandler(message, connection, transaction);
                return;
            }
            MethodInfo            mi;
            BrokerMethodAttribute statefulTransition             = new BrokerMethodAttribute(State, message.ContractName, message.Type);
            BrokerMethodAttribute statefulMessageTypeTransition  = new BrokerMethodAttribute(State, message.Type);
            BrokerMethodAttribute statelessTransition            = new BrokerMethodAttribute(message.ContractName, message.Type);
            BrokerMethodAttribute statelessMessageTypeTransition = new BrokerMethodAttribute(message.Type);

            if (m_dispatchMap.ContainsKey(statefulTransition))
            {
                mi = m_dispatchMap[statefulTransition];
            }
            else if (m_dispatchMap.ContainsKey(statefulMessageTypeTransition))
            {
                mi = m_dispatchMap[statefulMessageTypeTransition];
            }
            else if (m_dispatchMap.ContainsKey(statelessTransition))
            {
                mi = m_dispatchMap[statelessTransition];
            }
            else if (m_dispatchMap.ContainsKey(statelessMessageTypeTransition))
            {
                mi = m_dispatchMap[statelessMessageTypeTransition];
            }
            else
            {
                string exceptionMessage = "No broker method defined for message type '" + message.Type +
                                          "' on contract '" + message.ContractName + "'";
                if (State != -1)
                {
                    exceptionMessage += " in state " + State;
                }
                throw new InvalidOperationException(exceptionMessage);
            }
            mi.Invoke(this, new object[3] {
                message, connection, transaction
            });
            if (connection.State != ConnectionState.Open)
            {
                throw new ObjectDisposedException("Connection", "Method '" + mi.Name + "' closed the database connection.");
            }
        }