<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -11,7 +11,7 @@ namespace IServiceOriented.ServiceBus.UnitTests
     [ServiceContract]
     public interface IContract
     {
-        [OperationContract(IsOneWay=true)]
+        [OperationContract(IsOneWay=true, Action=&quot;PublishThis&quot;)]
         void PublishThis(string message);
     }
 
@@ -25,6 +25,7 @@ namespace IServiceOriented.ServiceBus.UnitTests
         volatile int failCount = 0;
         int failInterval = 0;
 
+
         public void PublishThis(string message)
         {
             int value = Interlocked.Increment(ref callCount);</diff>
      <filename>IServiceOriented.ServiceBus.UnitTests/IContract.cs</filename>
    </modified>
    <modified>
      <diff>@@ -6,6 +6,7 @@ using NUnit.Framework;
 using IServiceOriented.ServiceBus.Delivery;
 using IServiceOriented.ServiceBus.Dispatchers;
 using IServiceOriented.ServiceBus.Delivery.Formatters;
+using System.ServiceModel.Description;
 
 namespace IServiceOriented.ServiceBus.UnitTests
 {
@@ -16,6 +17,12 @@ namespace IServiceOriented.ServiceBus.UnitTests
         {
         }
 
+        public void TEst()
+        {
+            ContractDescription description = ContractDescription.GetContract(typeof(ISendMessageContract));
+            Console.WriteLine(description);
+        }
+
 
         [Test]
         public void QueuedDeliveryCore_Publishes_Response_Messages_For_TwoWay_Operation()</diff>
      <filename>IServiceOriented.ServiceBus.UnitTests/TestRequestResponse.cs</filename>
    </modified>
    <modified>
      <diff>@@ -41,7 +41,7 @@ namespace IServiceOriented.ServiceBus.UnitTests
                 string message = &quot;blah blah test test&quot;;
 
 
-                contractDispatcher.Dispatch(new MessageDelivery(endpoint.Id, typeof(IContract), &quot;http://tempuri.org/PublishThis&quot;, message, 3, new MessageDeliveryContext()));
+                contractDispatcher.Dispatch(new MessageDelivery(endpoint.Id, typeof(IContract), &quot;PublishThis&quot;, message, 3, new MessageDeliveryContext()));
 
                 Assert.AreEqual(1, ci.PublishedCount);
                 Assert.AreEqual(message, ci.PublishedMessages[0]);
@@ -102,8 +102,7 @@ namespace IServiceOriented.ServiceBus.UnitTests
 
                 runtime.Start();
 
-
-                string action = &quot;http://tempuri.org/IContract/PublishThis&quot;;
+                string action = &quot;PublishThis&quot;;
                 string body = &quot;blah blah test test&quot;;
 
                 XmlDocument document = new XmlDocument();</diff>
      <filename>IServiceOriented.ServiceBus.UnitTests/TestWcfDispatcher.cs</filename>
    </modified>
    <modified>
      <diff>@@ -19,45 +19,71 @@ namespace IServiceOriented.ServiceBus.Delivery.Formatters
 {
     internal class DataContractMessageDeliveryConverter : MessageDeliveryConverter
     {
-        public DataContractMessageDeliveryConverter(Type interfaceType)
+        public DataContractMessageDeliveryConverter(Type contractType)
+            : this(ContractDescription.GetContract(contractType))
         {
-            foreach (WcfMessageInformation information in WcfUtils.GetMessageInformation(interfaceType))
+            
+        }
+
+        public DataContractMessageDeliveryConverter(ContractDescription contract)
+        {
+            foreach (OperationDescription operation in contract.Operations)
             {
-                cacheSerializer(interfaceType, information.MessageType);
+                foreach (MessageDescription message in operation.Messages)
+                {
+                    cacheSerializer(operation, message);
+                }
             }
         }
 
-        Dictionary&lt;Type, DataContractSerializer&gt; _serializers = new Dictionary&lt;Type, DataContractSerializer&gt;();
+        Dictionary&lt;string, DataContractSerializer&gt; _serializers = new Dictionary&lt;string, DataContractSerializer&gt;();
 
-        void cacheSerializer(Type interfaceType, Type messageType)
+        void cacheSerializer(OperationDescription operation, MessageDescription message)
         {
-            if (!_serializers.ContainsKey(messageType))
+            if (!_serializers.ContainsKey(message.Action))
             {
-                _serializers.Add(messageType, new DataContractSerializer(messageType, WcfUtils.GetServiceKnownTypes(interfaceType)));
+                _serializers.Add(message.Action, message.Body.Parts.Count == 0 ? null : new DataContractSerializer(message.Body.Parts[0].Type, operation.KnownTypes));
             }
         }
 
-        DataContractSerializer getSerializer(Type interfaceType)
+        DataContractSerializer getSerializer(string action)
         {
             try
             {
-                return _serializers[interfaceType];
+                return _serializers[action];
             }
             catch (KeyNotFoundException)
             {
-                throw new InvalidOperationException(&quot;Unsupported interface or action&quot;);
+                throw new InvalidOperationException(&quot;Unsupported action&quot;);
             }
         }
 
         protected override Message ToMessageCore(MessageDelivery delivery)
         {
+            if (!_serializers.ContainsKey(delivery.Action))
+            {
+                throw new InvalidOperationException(&quot;Unsupported action&quot;);
+            }
+            
             return System.ServiceModel.Channels.Message.CreateMessage(MessageVersion.Default, delivery.Action, delivery.Message);
         }
 
         protected override object GetMessageObject(Message message)
         {
-            var serializer = getSerializer(Type.GetType(message.Headers.GetHeader&lt;string&gt;(MessageTypeHeader, MessagingNamespace)));
-            return serializer.ReadObject(message.GetReaderAtBodyContents());
+            var serializer = getSerializer(message.Headers.Action);
+            if (serializer != null)
+            {
+                return serializer.ReadObject(message.GetReaderAtBodyContents());
+            }
+            else
+            {
+                return null;
+            }
+        }
+
+        public override IEnumerable&lt;string&gt; SupportedActions
+        {
+            get { return _serializers.Keys; }
         }
     }
 }</diff>
      <filename>IServiceOriented.ServiceBus/Delivery/Formatters/DataContractMessageDeliveryConverter.cs</filename>
    </modified>
    <modified>
      <diff>@@ -19,49 +19,78 @@ namespace IServiceOriented.ServiceBus.Delivery.Formatters
 {
     internal class MessageContractMessageDeliveryConverter : MessageDeliveryConverter
     {
-        public MessageContractMessageDeliveryConverter(Type contractType)
+        public MessageContractMessageDeliveryConverter(Type contractType) : this(ContractDescription.GetContract(contractType))
         {
-            foreach (WcfMessageInformation information in WcfUtils.GetMessageInformation(contractType))
-            {                
-                cacheConverter(information.MessageType, information.Action);
+            
+        }
+
+        public MessageContractMessageDeliveryConverter(ContractDescription contract)
+        {
+            foreach (OperationDescription operation in contract.Operations)
+            {
+                foreach (MessageDescription message in operation.Messages)
+                {
+                    if (message.MessageType == null &amp;&amp; message.Body.Parts.Count &gt; 0)
+                    {
+                        throw new InvalidOperationException(&quot;Unsupported message contract format&quot;);
+                    }
+                    cacheConverter(message.Action, message.MessageType);
+                }
             }
         }
 
         Dictionary&lt;string, TypedMessageConverter&gt; _converterHash = new Dictionary&lt;string, TypedMessageConverter&gt;();
 
-        void cacheConverter(Type objType, string action)
+        void cacheConverter(string action, Type messageType)
         {
-            string key = objType + &quot;:&quot; + action;
-            if (!_converterHash.ContainsKey(key))
-            {
-                _converterHash.Add(key, (TypedMessageConverter)TypedMessageConverter.Create(objType, action));
+            if (!_converterHash.ContainsKey(action))
+            {                
+                _converterHash.Add(action, messageType == null ? null : (TypedMessageConverter)TypedMessageConverter.Create(messageType, action));
             }
         }
 
-        TypedMessageConverter getCachedConverter(Type objType, string action)
+        TypedMessageConverter getCachedConverter(string action)
         {
-            string key = objType + &quot;:&quot; + action;
             try
             {
-                return (TypedMessageConverter)_converterHash[key];
+                return (TypedMessageConverter)_converterHash[action];
             }
             catch (KeyNotFoundException)
             {
-                throw new InvalidOperationException(&quot;Unsupported interface or action&quot;);
+                throw new InvalidOperationException(&quot;Unsupported action&quot;);
             }
         }
 
         protected override object GetMessageObject(Message message)
         {            
-            TypedMessageConverter converter = getCachedConverter(Type.GetType(message.Headers.GetHeader&lt;string&gt;(MessageTypeHeader, MessagingNamespace)), message.Headers.Action);
+            TypedMessageConverter converter = getCachedConverter(message.Headers.Action);
             return converter.FromMessage(message);
         }
 
         protected override Message ToMessageCore(MessageDelivery delivery)
         {
-            Type objType = delivery.Message.GetType();            
-            TypedMessageConverter converter = getCachedConverter(objType, delivery.Action);
-            return converter.ToMessage(delivery.Message);        
+            if (!_converterHash.ContainsKey(delivery.Action))
+            {
+                throw new InvalidOperationException(&quot;Unsupported action&quot;);
+            }
+
+            TypedMessageConverter converter = getCachedConverter(delivery.Action);
+            if (converter != null)
+            {
+                return converter.ToMessage(delivery.Message);
+            }
+            else
+            {
+                return null;
+            }
+        }
+
+        public override IEnumerable&lt;string&gt; SupportedActions
+        {
+            get 
+            {
+                return _converterHash.Keys;
+            }
         }
     }
 </diff>
      <filename>IServiceOriented.ServiceBus/Delivery/Formatters/MessageContractMessageDeliveryConverter.cs</filename>
    </modified>
    <modified>
      <diff>@@ -20,7 +20,6 @@ namespace IServiceOriented.ServiceBus.Delivery.Formatters
 {
     public abstract class MessageDeliveryConverter
     {
-        public const string MessageTypeHeader = &quot;messageType&quot;;
         public const string MaxRetriesHeader = &quot;maxRetries&quot;;
         public const string RetryCountHeader = &quot;retryCount&quot;;
         public const string MessageIdHeader = &quot;messageId&quot;;
@@ -42,7 +41,6 @@ namespace IServiceOriented.ServiceBus.Delivery.Formatters
             Message msg = ToMessageCore(delivery);                        
             
             msg.Headers.Add(System.ServiceModel.Channels.MessageHeader.CreateHeader(ContextHeader, MessagingNamespace, delivery.Context)); 
-            msg.Headers.Add(System.ServiceModel.Channels.MessageHeader.CreateHeader(MessageTypeHeader, MessagingNamespace, objType.AssemblyQualifiedName));
             msg.Headers.Add(System.ServiceModel.Channels.MessageHeader.CreateHeader(MaxRetriesHeader, MessagingNamespace, delivery.MaxRetries));
             msg.Headers.Add(System.ServiceModel.Channels.MessageHeader.CreateHeader(RetryCountHeader, MessagingNamespace, delivery.RetryCount));
             msg.Headers.Add(System.ServiceModel.Channels.MessageHeader.CreateHeader(MessageIdHeader, MessagingNamespace, delivery.MessageDeliveryId));
@@ -74,13 +72,24 @@ namespace IServiceOriented.ServiceBus.Delivery.Formatters
             return delivery;
         }
 
+        public abstract IEnumerable&lt;string&gt; SupportedActions
+        {
+            get;
+        }
+        
+
         public static MessageDeliveryConverter CreateConverter(Type interfaceType)
         {
-            if (WcfUtils.UsesMessages(interfaceType))
+            ContractDescription description = ContractDescription.GetContract(interfaceType);
+
+            int rawMessageOperationCount = description.Operations.Where( o =&gt; o.Messages.First().Body.Parts.First().Type == typeof(Message)).Count();
+            int messageContractOperationCount = description.Operations.Where(o =&gt; o.Messages.First().MessageType != null).Count();
+            
+            if (rawMessageOperationCount &gt; 0)
             {
                 return new RawMessageMessageDeliveryConverter(interfaceType);
             }
-            else if (WcfUtils.UsesMessageContracts(interfaceType))
+            else if (messageContractOperationCount &gt; 0)
             {
                 return new MessageContractMessageDeliveryConverter(interfaceType);
             }
@@ -89,6 +98,18 @@ namespace IServiceOriented.ServiceBus.Delivery.Formatters
                 return new DataContractMessageDeliveryConverter(interfaceType);
             }
         }
+
+
+        public static MessageDeliveryConverter CreateConverter(params Type[] contractTypes)
+        {
+            MessageDeliveryConverter[] converters = new MessageDeliveryConverter[contractTypes.Length];
+
+            for(int i = 0; i &lt; contractTypes.Length; i ++)
+            {
+                converters[i] = CreateConverter(contractTypes[i]);
+            }
+            return new CompositeMessageDeliveryConverter(converters);
+        }
     }
 
     </diff>
      <filename>IServiceOriented.ServiceBus/Delivery/Formatters/MessageDeliveryConverter.cs</filename>
    </modified>
    <modified>
      <diff>@@ -215,7 +215,7 @@ namespace IServiceOriented.ServiceBus.Delivery
         }
         const int FUTURE_SLEEP_MS = 100;
         const int RETRY_SLEEP_MS = 100;
-        const int DEQUEUE_TIMEOUT_SECONDS = 5;
+        const int DEQUEUE_TIMEOUT_SECONDS = 1;
 
         List&lt;Thread&gt; _workerThreads = new List&lt;Thread&gt;();
         object _workerThreadsLock = new object();</diff>
      <filename>IServiceOriented.ServiceBus/Delivery/QueuedDeliveryCore.cs</filename>
    </modified>
    <modified>
      <diff>@@ -10,6 +10,7 @@ using IServiceOriented.ServiceBus.Threading;
 using IServiceOriented.ServiceBus.Collections;
 using IServiceOriented.ServiceBus.Listeners;
 using System.ServiceModel.Channels;
+using System.ServiceModel.Description;
 
 namespace IServiceOriented.ServiceBus.Dispatchers
 {    
@@ -42,24 +43,28 @@ namespace IServiceOriented.ServiceBus.Dispatchers
 
             Dictionary&lt;string, MethodInfo&gt; actionLookup = new Dictionary&lt;string, MethodInfo&gt;();
             Dictionary&lt;string, string&gt; replyActionLookup = new Dictionary&lt;string, string&gt;();
-            foreach (MethodInfo method in endpoint.ContractType.GetMethods())
+            foreach (OperationDescription operation in ContractDescription.GetContract(endpoint.ContractType).Operations)
             {
-                if (WcfUtils.IsServiceMethod(method))
+                MessageDescription requestMessage = operation.Messages.Where(md =&gt; md.Direction == MessageDirection.Input).First();
+                MessageDescription responseMessage = operation.Messages.Where(md =&gt; md.Direction == MessageDirection.Output).FirstOrDefault();
+                
+                if (requestMessage.Action == &quot;*&quot;)
                 {
-                    string action = WcfUtils.GetAction(endpoint.ContractType, method);
-                    if (action == &quot;*&quot;)
+                    _passThrough = true;
+                }
+
+                actionLookup.Add(requestMessage.Action, operation.SyncMethod);
+
+                if (responseMessage != null)
+                {
+                    string replyAction = responseMessage.Action;
+
+                    if (replyAction != null)
                     {
-                        _passThrough = true;
+                        replyActionLookup.Add(requestMessage.Action, replyAction);
                     }
-                    actionLookup.Add(action, method);
-                    
-                    string replyAction = WcfUtils.GetReplyAction(endpoint.ContractType, method);
-                    
-                    if(replyAction != null)
-                    {
-                        replyActionLookup.Add(action, replyAction);
-                    }                 
                 }
+            
             }
             lookup.MethodLookup = actionLookup;
             lookup.ReplyActionLookup = replyActionLookup;
@@ -176,9 +181,18 @@ namespace IServiceOriented.ServiceBus.Dispatchers
         [NonSerialized]
         ActionLookup _lookup;
 
-        public static MessageFilter CreateMessageFilter(Type interfaceType)
-        {               
-            return new TypedMessageFilter(WcfUtils.GetMessageInformation(interfaceType).Select(mi =&gt; mi.MessageType).ToArray());
+        public static MessageFilter CreateMessageFilter(Type contractType)
+        {
+            ContractDescription description = ContractDescription.GetContract(contractType);
+            List&lt;Type&gt; messageTypes = new List&lt;Type&gt;();
+            foreach (OperationDescription operation in description.Operations)
+            {
+                foreach (MessageDescription message in operation.Messages)
+                {
+                    messageTypes.Add(message.Body.Parts[0].Type);
+                }
+            }
+            return new TypedMessageFilter(messageTypes.ToArray());
         }
     }
 </diff>
      <filename>IServiceOriented.ServiceBus/Dispatchers/WcfProxyDispatcher.cs</filename>
    </modified>
    <modified>
      <diff>@@ -93,6 +93,7 @@
   &lt;/ItemGroup&gt;
   &lt;ItemGroup&gt;
     &lt;Compile Include=&quot;DeliveryException.cs&quot; /&gt;
+    &lt;Compile Include=&quot;Delivery\Formatters\CompositeMessageDeliveryConverter.cs&quot; /&gt;
     &lt;Compile Include=&quot;Delivery\Formatters\ConverterMessageDeliveryReader.cs&quot; /&gt;
     &lt;Compile Include=&quot;Delivery\Formatters\ConverterMessageDeliveryReaderFactory.cs&quot; /&gt;
     &lt;Compile Include=&quot;Delivery\Formatters\ConverterMessageDeliveryWriter.cs&quot; /&gt;
@@ -165,7 +166,6 @@
     &lt;Compile Include=&quot;Listeners\WcfListener.cs&quot; /&gt;
     &lt;Compile Include=&quot;Listeners\WcfServiceHostFactory.cs&quot; /&gt;
     &lt;Compile Include=&quot;Services\WcfManagementService.cs&quot; /&gt;
-    &lt;Compile Include=&quot;WcfUtils.cs&quot; /&gt;
   &lt;/ItemGroup&gt;
   &lt;ItemGroup&gt;
     &lt;None Include=&quot;ClassDiagram.cd&quot; /&gt;</diff>
      <filename>IServiceOriented.ServiceBus/IServiceOriented.ServiceBus.csproj</filename>
    </modified>
    <modified>
      <diff>@@ -27,8 +27,11 @@ namespace IServiceOriented.ServiceBus.Listeners
 
         protected override void OnStop()
         {
-            CommunicationObject.Close();
-            CommunicationObject = null;
+            if (CommunicationObject != null)
+            {
+                CommunicationObject.Close();
+                CommunicationObject = null;
+            }
             base.OnStop();
         }
         </diff>
      <filename>IServiceOriented.ServiceBus/Listeners/WcfListener.cs</filename>
    </modified>
    <modified>
      <diff>@@ -12,6 +12,7 @@ using System.Reflection.Emit;
 using System.Security.Principal;
 
 using IServiceOriented.ServiceBus.Collections;
+using System.ServiceModel.Description;
 
 namespace IServiceOriented.ServiceBus.Listeners
 {
@@ -68,19 +69,16 @@ namespace IServiceOriented.ServiceBus.Listeners
             CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(typeof(ServiceBehaviorAttribute).GetConstructor(new Type[] { }), new object[] { }, new PropertyInfo[] { typeof(ServiceBehaviorAttribute).GetProperty(&quot;InstanceContextMode&quot;), typeof(ServiceBehaviorAttribute).GetProperty(&quot;ConcurrencyMode&quot;), typeof(ServiceBehaviorAttribute).GetProperty(&quot;Namespace&quot;) }, new object[] { InstanceContextMode.Single, ConcurrencyMode.Multiple, &quot;http://iserviceoriented.com/serviceBus/2008/&quot; });                    
             typeBuilder.SetCustomAttribute(attributeBuilder);
 
-            foreach (MethodInfo methodInfo in interfaceType.GetMethods())
+            foreach (OperationDescription od in ContractDescription.GetContract(interfaceType).Operations)
             {
-                // Only add methods with OperationContractAttribute
-                if(WcfUtils.IsServiceMethod(methodInfo))
+                MethodInfo method = od.SyncMethod;
+                MessageDescription message = od.Messages.Where(m =&gt; m.Direction == MessageDirection.Input).First();
+                if (message.Body.Parts.Count &gt; 1)
                 {
-                    string action = WcfUtils.GetAction(interfaceType, methodInfo);                    
-                    if (methodInfo.GetParameters().Length != 1)
-                    {
-                        continue; // skip methods that don't accept a single parameter
-                    }
-
-                    definePublishOverride(interfaceType, typeBuilder, methodInfo, action);
+                    throw new InvalidOperationException(&quot;Only single parameter methods are currently supported&quot;);
                 }
+
+                definePublishOverride(interfaceType, typeBuilder, method, message.Action);
             }
             Type impType = typeBuilder.CreateType();
             return impType;        </diff>
      <filename>IServiceOriented.ServiceBus/Listeners/WcfServiceHostFactory.cs</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>IServiceOriented.ServiceBus/WcfUtils.cs</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>bbc32282b9f135da2fa1c26eb10df08a933ba1ad</id>
    </parent>
  </parents>
  <author>
    <name>jezell</name>
    <email>jezell@gmail.com</email>
  </author>
  <url>http://github.com/jezell/iserviceoriented/commit/a13d552fd34aff3ff8c7ed61e0be8031a72922eb</url>
  <id>a13d552fd34aff3ff8c7ed61e0be8031a72922eb</id>
  <committed-date>2008-10-16T07:51:45-07:00</committed-date>
  <authored-date>2008-10-16T07:51:45-07:00</authored-date>
  <message>Replace WcfUtils with calls to WCF metadata classes, support for ContractDescription in serialization, support for multiple contract serialization</message>
  <tree>a26d7a9277541d45912009231760eb42ec0d5bb4</tree>
  <committer>
    <name>jezell</name>
    <email>jezell@gmail.com</email>
  </committer>
</commit>
