8

I am running into a base-typing problem with messages I am attempting to publish through MassTransit. Consider the following:

[Serializable]
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);
    }

}

[Serializable]
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?

EDIT: I have attempted to change my settings to use BinarySerialization like so:

 Bus.Initialize(sbc =>
     {
         sbc.UseBinarySerializer();
     });

and have not yielded any change in behavior. The only way that I have been able to get my Consumes<PersonCreated> class to be called is to explicitly cast an event to PersonCreated type.

Jeff Fritz
  • 9,821
  • 7
  • 42
  • 52

1 Answers1

10

Edit: Serializer doesn't matter here. I didn't think this through.

You could invoke Bus.Instance.Publish with the right type information by doing reflection on the Event object and getting it's actual type as well. This is going to be some awkward code but once it's done likely easy to reuse. In Magnum we have an extension method to help with this.

Bus.Instance.FastInvoke(new[]{ event.GetType() }, "Publish", event);

Join us on the mailing list, http://groups.google.com/group/masstransit-discuss, and we'll be happy to discuss in more details.

Travis
  • 10,444
  • 2
  • 28
  • 48
  • Ahh.. I've been scanning the discussion list for this problem today, and thought this was a great place to post, as more would see it here. I will cross-post – Jeff Fritz Aug 29 '11 at 23:49
  • We, the MT developers, will see the email before we'll see SO post. We try to be pretty responsive to questions. – Travis Aug 29 '11 at 23:56
  • I have updated my question to include information about my attempt to use the BinarySerializer – Jeff Fritz Aug 30 '11 at 03:15
  • The serializer would need to be changed to get the type information on the other end. The publishing process only checkes what type information it gets from `Publish`'s `T` at compile time (or run if you use reflection). – Travis Aug 30 '11 at 12:20
  • I did not find Magnum embedded in the MassTransit.dll, but did see it downloaded as a prereq for MassTransit 2.0.4 and referenced that. – Jeff Fritz Aug 30 '11 at 14:49
  • 1
    Yeah, we can't ILMerge Magnum, since the state machine used for sagas is exposed. With NuGet, it's so much easier to just add a dependency anyway! – Chris Patterson Sep 04 '11 at 14:20