title: Derived types are not published to consumers in MassTransit
body: <p>I am having issues publishing generic messages for derived types and having the handler invoked using MassTransit v2.8.0.</p>
  
  <p>If I publish a message of type <code>HtmlBlockNewMessage</code>, the consumer is never invoked. If I publish a <code>ServiceBusMessage</code> object and change the consumer to <code>Consumes&lt;ServiceBusMessage&gt;.Context</code>, the consumer is invoked.</p>
  
  <p>The code fails for a derived type. It only works for the parent type (ServiceBusMessage).</p>
  
  <p>Types:</p>
  
  <pre><code>[Serializable]
  public class ServiceBusMessage
  {
  }
  
  [Serializable]
  public class ServiceBusResponse
  {
      public int ResultCode { get; set; } 
  }
  
  // Request
  [Serializable]
  public class ContentItemMessage : ServiceBusMessage
  {
      public string SiteId { get; set; }
      public string PageId { get; set; }
      public string ContentItemId { get; set; }
  }
  
  [Serializable]
  public class HtmlBlockNewMessage : ContentItemMessage
  {
      public string HtmlData { get; set; }
  }
  
  // Response
  [Serializable]
  public class ContentItemMessageResponse : ServiceBusResponse
  {
      public string Name { get; set; }
      public string ItemType { get; set; }
      public string ItemHandler { get; set; }       
  }
  
  [Serializable]
  public class HtmlBlockNewMessageResponse : ContentItemMessageResponse
  {
      public string DataId { get; set; }
  }
  </code></pre>
  
  <p>Consumer:</p>
  
  <pre><code>public class HtmlBlockConsumer : Consumes&lt;HtmlBlockNewMessage&gt;.Context
  {
      private IHtmlDataService htmlDataService;
      public static ILogger Logger { get; set; }
  
      public HtmlBlockConsumer()
          : this(null)
      {
      }
  
      public HtmlBlockConsumer(IHtmlDataService htmlDataService)
      {
          Logger = Log4NetLogger.GetLogger();
  
          this.htmlDataService = htmlDataService ?? IoC.Container.Resolve&lt;IHtmlDataService&gt;();
      }
  
      public void Consume(IConsumeContext&lt;HtmlBlockNewMessage&gt; message)
      {
      // Do some stuff
  
          message.Respond(new HtmlBlockNewMessageResponse() { ResultCode = 1 } );
      }
  </code></pre>
  
  <p>}</p>
  
  <p>Bus registration from publisher side:</p>
  
  <pre><code>        var bus = ServiceBusFactory.New(sbc =&gt;
          {
              sbc.EnableMessageTracing();
  
              sbc.UseMsmq();
              sbc.VerifyMsmqConfiguration();
              sbc.UseMulticastSubscriptionClient();
              sbc.SetNetwork("Test");
              sbc.UseXmlSerializer();
              sbc.UseControlBus();
  
              sbc.ReceiveFrom("msmq://localhost/AuctionCMS.Web.Publisher");
  
              MtServiceBus.ValidateBus(sbc);
          });
  
          IoC.Container.RegisterInstance(bus);
  </code></pre>
  
  <p>Bus registration from consumer side:</p>
  
  <pre><code>        var bus = ServiceBusFactory.New(sbc =&gt;
          {
              sbc.EnableMessageTracing();
  
              sbc.UseMsmq();
              sbc.VerifyMsmqConfiguration();
              sbc.UseMulticastSubscriptionClient();
              sbc.SetNetwork("Test");
              sbc.UseXmlSerializer();
              sbc.UseControlBus();
  
              sbc.ReceiveFrom("msmq://localhost/AuctionCMS.Consumer");
  
              sbc.Subscribe(subs =&gt;
              {
                  // These are being manually registered due to some issues getting
                  // StructureMap to scan my assemblies
                  subs.Instance(new HtmlBlockConsumer());
                  subs.Instance(new BrowserConsumer());
                  subs.Instance(new OfferConsumer());
              });
          });
  
          IoC.Container.RegisterInstance(bus);
  </code></pre>
  
  <p>My publish extension:</p>
  
  <pre><code>    public static TR Publish&lt;T, TR&gt;(this IServiceBus bus, T message) where T : ServiceBusMessage where TR : ServiceBusResponse
      {
          TR response = null;
  
          IoC.Container.Resolve&lt;IServiceBus&gt;().PublishRequest(message, callback =&gt;
              {
                  callback.SetTimeout(10.Seconds());
  
                  try
                  {
                      callback.Handle&lt;TR&gt;(m =&gt;
                          {
                              response = m; /
                          });
                  }
                  catch (Exception ex)
                  {
  
                      throw;
                  }
              });
  
          return response;
      }
  </code></pre>
  
  <p>Calling code:</p>
  
  <pre><code>// First I create a message specific to the type of action I am performing 
  
  var message = new HtmlBlockNewMessage() { HtmlData = "Hello" }; 
  
  // Then I call a function which accepts a ContentItemMessage and calls Publish
  
  public void AddContentItem(ContentItemMessage message) 
  {
      // Do some preprocessing
  
      // This call times out
      var response = this.auctionCmsServices.Bus.Publish&lt;ContentItemMessage,
            ContentItemMessageResponse&gt;(message);
  
      // Do some more processing
  
  }
  </code></pre>
  
  <p>This is the exception</p>
  
  <pre><code>[RequestTimeoutException: Timeout waiting for response, RequestId: 54910000-307f-20cf-c0c2-08d06b31cf6f]
     MassTransit.RequestResponse.RequestImpl`1.Wait() in d:\BuildAgent-03\work\aa063b4295dfc097\src\MassTransit\RequestResponse\RequestImpl.cs:124
     MassTransit.RequestResponseExtensions.PublishRequest(IServiceBus bus, TRequest message, Action`1 configureCallback) in d:\BuildAgent-03\work\aa063b4295dfc097\src\MassTransit\RequestResponseExtensions.cs:31
     AuctionCMS.Framework.ServiceBus.MtServiceBus.Publish(IServiceBus bus, T message) in c:\Users\rick\Documents\Visual Studio 2012\Projects\AuctionCMS\AuctionCMS.Framework\ServiceBus\MtServiceBus.cs:24
     AuctionCMS.Framework.Entity.Page.AddContentItem(ISite site, String zone, Int32 location, ContentItemMessage message) in c:\Users\rick\Documents\Visual Studio 2012\Projects\AuctionCMS\AuctionCMS.Framework\Entity\Page.cs:48
     AuctionCMS.Framework.Entity.Site.SetDefaultContent() in c:\Users\rick\Documents\Visual Studio 2012\Projects\AuctionCMS\AuctionCMS.Framework\Entity\Site.cs:117
     AuctionCMS.Web.Controllers.AdminSitesController.NewSite(SiteNewModel model, HttpPostedFileBase file) in c:\Users\rick\Documents\Visual Studio 2012\Projects\AuctionCMS\AuctionCMS.Web\Controllers\AdminSitesController.cs:69
     lambda_method(Closure , ControllerBase , Object[] ) +179
     System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +261
     System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +39
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass42.&lt;BeginInvokeSynchronousActionMethod&gt;b__41() +34
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass39.&lt;BeginInvokeActionMethodWithFilters&gt;b__33() +124
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass4f.&lt;InvokeActionMethodFilterAsynchronously&gt;b__49() +838059
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass4f.&lt;InvokeActionMethodFilterAsynchronously&gt;b__49() +838059
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass4f.&lt;InvokeActionMethodFilterAsynchronously&gt;b__49() +838059
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass4f.&lt;InvokeActionMethodFilterAsynchronously&gt;b__49() +838059
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass37.&lt;BeginInvokeActionMethodWithFilters&gt;b__36(IAsyncResult asyncResult) +15
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass2a.&lt;BeginInvokeAction&gt;b__20() +33
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass25.&lt;BeginInvokeAction&gt;b__22(IAsyncResult asyncResult) +838644
     System.Web.Mvc.&lt;&gt;c__DisplayClass1d.&lt;BeginExecuteCore&gt;b__18(IAsyncResult asyncResult) +28
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass4.&lt;MakeVoidDelegate&gt;b__3(IAsyncResult ar) +15
     System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +65
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass4.&lt;MakeVoidDelegate&gt;b__3(IAsyncResult ar) +15
     System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +51
     System.Web.Mvc.&lt;&gt;c__DisplayClass8.&lt;BeginProcessRequest&gt;b__3(IAsyncResult asyncResult) +42
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass4.&lt;MakeVoidDelegate&gt;b__3(IAsyncResult ar) +15
     System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +51
     System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +606
     System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously) +288
  </code></pre>
  
  <p>Edit:</p>
  
  <p>I went with a generic approach to solve this. It's a but ugly from the caller's perspective, but it works.</p>
  
  <pre><code>   public TR AddContentItem&lt;T, TR&gt;(T message) where T : ContentItemMessage where TR : ContentItemMessageResponse
      {
          var response = this.auctionCmsServices.Bus.Publish&lt;T, TR&gt;(message);
  
          return response;
      }
  </code></pre>
  
  <p>The calling code now looks like this:</p>
  
  <blockquote>
    <p>page.AddContentItem(new HtmlBlockNewMessage() { HtmlData =
    "This is some <b>html</b>" });</p>
  </blockquote>