MassTransit generic message mis-typing

535 views
Skip to first unread message

Jeff

unread,
Aug 29, 2011, 9:46:34 PM8/29/11
to masstransit-discuss
I am running into a base-typing problem with messages I am attempting
to publish through MassTransit. Consider the following:

public abstract class Event : CorrelatedBy<Guid> {

public Guid CorrelationId { get; set; }

public abstract string EventName { get; }

public override string ToString() {
return string.Format("{0} - {1}", EventName,
CorrelationId);
}

}


public class PersonCreated : Event {

public PersonCreated(Guid personId, string firstName, string
lastName) {

PersonId = personId;
FirstName = firstName;
LastName = lastName;

}

public readonly Guid PersonId;
public readonly string FirstName;
public readonly string LastName;

}


However, when I attempt to publish a collection of abstract events
with something like:

public void PublishEvents(IEnumerable<Event> events) {

foreach (var e in events) {

Bus.Instance.Publish(e);

}

}

I do NOT receive any events out of this collection, regardless of
their concrete types. If I cast the event to its proper concrete type
before publishing on the bus, I do receive the message properly.

Any ideas as to how I can correct this to allow my abstract collection
of Events to be processed without casting each one?

Jeff

unread,
Aug 29, 2011, 11:18:22 PM8/29/11
to masstransit-discuss
I have attempted to convert to using the BinarySerializer, and I still
see the same behavior. The only way I can get the PersonCreated Event
to appear is to explicitly cast the event before calling Bus.Publish

Jeff

Nik Govorov

unread,
Aug 30, 2011, 2:50:26 AM8/30/11
to masstrans...@googlegroups.com
Hi Jeff.
I guess it is by design. You are using generic method Publish<T>, so message type extracted from T.
In your case you can write your own bus extension method that uses FastInvoker from magnum.

    public static class ServiceBusEx
    {
        public static UnTypedMessagePublishingExtension Extensions(this IServiceBus self)
        {
            return new UnTypedMessagePublishingExtension(self);
        }
    }

    public class UnTypedMessagePublishingExtension
    {
        private IServiceBus bus;

        public UnTypedMessagePublishingExtension(IServiceBus bus)
        {
            this.bus = bus;
        }

        public void Publish(object message)
        {
            this.FastInvoke(new[] {message.GetType()}, "Publish", message);
        }

        protected void Publish<T>(T message) where T : class
        {
            bus.Publish(message, ctx => { });
        }
    }


Usage:

bus.Extensions().Publish(new SubMessage {Name = "Jeff"});


Dru Sellers

unread,
Aug 30, 2011, 9:20:53 AM8/30/11
to masstrans...@googlegroups.com
What does your subscription code look like?

-d

> --
> You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
> To post to this group, send email to masstrans...@googlegroups.com.
> To unsubscribe from this group, send email to masstransit-dis...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/masstransit-discuss?hl=en.
>

Dru Sellers

unread,
Aug 30, 2011, 9:24:09 AM8/30/11
to masstrans...@googlegroups.com
Hi Nik, you are correct. MassTransit depends heavily on the message type for message routing. I am not sure what it is you are trying to accomplish Jeff with the base class.  Care to explain?

-d
--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.

Jeffrey Fritz

unread,
Aug 30, 2011, 10:12:11 AM8/30/11
to masstrans...@googlegroups.com
I am using a base Event class to ensure that all of my events that I publish are CorrelatedBy<Guid> as well as to ensure several required properties that I did not disclose here.  

I am using an event source, and would like to be able to ensure that only Event objects are saved, not Command objects.

Consequently, I have an block of code I am working with that looks something like:

public static void Dispatch(Commit c) {
    foreach (var e in c.Events) {
        Bus.Instance.Publish(e);
    }
}

... and the event that is published is of the base class Event, not the concrete PersonCreated type.

I have tried Nik's recommendation, and the data is now flowing properly.


Jeff

Nik Govorov

unread,
Aug 30, 2011, 10:50:54 AM8/30/11
to masstrans...@googlegroups.com
Hi Dru, Jeff just wants to have non-generic version of the 'Publish' method to determine message type in 'runtime'.

Dru Sellers

unread,
Aug 30, 2011, 11:03:31 AM8/30/11
to masstrans...@googlegroups.com
Jeff, care to wrap up your publish method up into an extention method and send a pull request. 

-d

On Aug 30, 2011, at 9:50 AM, Nik Govorov <nikita....@gmail.com> wrote:

Hi Dru, Jeff just wants to have non-generic version of the 'Publish' method to determine message type in 'runtime'.

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.

Chris Patterson

unread,
Aug 30, 2011, 2:05:00 PM8/30/11
to masstrans...@googlegroups.com
I've got one ready to commit, just need to get back to bandwidth land. 

It's basically the same. 

--
Chris Patterson

Jeffrey Fritz

unread,
Aug 30, 2011, 2:50:05 PM8/30/11
to masstrans...@googlegroups.com
It sounds like you beat me to it...  If you still need it later this evening, I'll submit a pull request.


Jeff
Reply all
Reply to author
Forward
0 new messages