Serialization Issues

78 views
Skip to first unread message

craiggwilson

unread,
Nov 20, 2009, 3:47:48 PM11/20/09
to masstransit-discuss
I'm sending a message that looks similiar to this:

public class AnimalMessage
{
public Animal Animal { get; set; }
}

public abstract class Animal
{

}

public class Lion : Animal
{

}

When I use bus.Publish(new AnimalMessage() { new Lion() }), I never
receive a Lion, but only a proxied form of Animal.

Is there a way to change the serializer to use the
DataContractSerializer and use the KnownType attributes? Otherwise,
what am I missing?

Thanks for your help...

Chris Patterson

unread,
Nov 20, 2009, 7:42:20 PM11/20/09
to masstrans...@googlegroups.com
This falls into the area of messages being a contract. 

Animal is part of the contract, not Lion. 

Therefore, anything related to Lion is not part of the reception of the message.

There are good reasons why you do not want your messages to have this type of behavior. And the only reason I can think that you would want the object to be an actual Lion is because there is some type of behavior associated with it.

If you could explain your exact requirements (because I honestly don't think you're building a wildlife inventory application) it might help to provide some more clear guidance in this area.

Messages should be treated like DTOs (data-transfer objects) and as such should not include behavior.

The abstract/proxy is there so that you can subscribe to an Animal, and get a message when anything that implements Animal is published.




--

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=.



Chris Patterson



craiggwilson

unread,
Nov 20, 2009, 10:57:42 PM11/20/09
to masstransit-discuss
You're right. Not a wildlife management system. I didn't use the
real terminology because it is very similiar to MassTransit's own
(endpoints, transports, etc...)

I have different types of endpoints (IPEndPoints, SmsEndPoints,
etc...) and each one has a different configuration. Essentially, when
a message (from a gps device) arrives, we publish a message including
where it came from. It is important that we know where it came from
so we can update the devices location. However, there are many
different type of devices and we have split the processing of the
message from the receipt of it. Hence, we need to communicate to the
processor where the message came from.

These are in fact transfer objects and have no behaviour at all. Each
end translates them appropriately to their related domain concept. I
have worked a lot with WCF and it supports this type of inheritance
using the KnownType attribute and didn't know what my alternatives
were.
> chrisfromtu...@gmail.com

Chris Patterson

unread,
Nov 21, 2009, 2:29:32 PM11/21/09
to masstrans...@googlegroups.com
Well, the way the serializer was written, if you have a member that has a type, it will serialize it as that type rather than the type that was serialized.

It used to always serialize the type of the object, and it still could but you can't specify an interface/class for the member. It would have to be of type object, in which case it will always serialize it as the actual type.

You can see an example of this in the XmlMessageEnvelope, which has Message as an object property so that the appropriate type is serialized with the envelope.

If you want to write a DataContractMessageSerializer and mark up all your messages and stuff, you can give it a shot. Having to know all the types in advance is in my opinion, a pain in the butt. Both the XmlSerializer in .NET and the DataContractSerializer are painful to use and an artifact of the SOAP style unpinning of WCF. 

While I can't possibly understand all the design decisions that went into your choice of using an object type as the identifier for the source of the message, I'm not sure I would have made that at implicit aspect of the message contract. From my armchair looking in, I would prefer to have some sort of identifier that identifies the device/type of device from which the message originated as part of the explicit message contract.

Just my initial thoughts, hopefully that helps you in your design path.

CP



For more options, visit this group at http://groups.google.com/group/masstransit-discuss?hl=.



Chris Patterson



craiggwilson

unread,
Nov 21, 2009, 3:08:15 PM11/21/09
to masstransit-discuss
Ok, thanks.

I do indeed have an enum that identifies (in this case) the type of
endpoint (IP, Sms, etc...).But because each different type of endpoint
has different attributes about it that also need to be communicated,
we chose the natural object -oriented approach (inheritance) rather
than use a dictionary. The message itself looks as follows.

public class ReceivedDataMessage
{
public DateTime ReceivedDateTime { get; set; }
public int BindingDefinitionId { get; set; }
public EndPointInfo DeviceEndPointInfo { get; set; }
public byte[] Data { get; set; }
}

The endpoint in the message could be any kind of endpoint and the type
and attributes need to be communicated. There is a lot of overhead
involved in parsing the data, which is why it was offloaded to another
service as it doesn't need to be handled in real time.

We do know all the types ahead of time as we have the ability to share
the Messages assembly which takes no references to the rest of the
domain model.

As far as creating the serializer, that doesn't seem like a huge issue
-> just implement IMessageSerializer. However, what does have me a
little confused is to how to get the Msmq endpoints to use this
serializer... I'm using the windsor container for IoC.

Thanks for your help Chris...

Dru Sellers

unread,
Nov 22, 2009, 7:57:55 AM11/22/09
to masstrans...@googlegroups.com
One thing to be careful of is this statement.

"chose the natural object -oriented approach (inheritance) rather than ..."

I hadn't really thought much about it, and I am not really sure either, but I bet that the design of a message shouldn't be thought of as 'object-y'. objects have behaviour and messages do not.

So, what are we to do? Not knowing your model and what the differences are, I offer the following:

instead of inheritance, try composition. is your message really two messages that need to be sent in one 'envelope'? 

-d

craiggwilson

unread,
Nov 22, 2009, 6:32:37 PM11/22/09
to masstransit-discuss
That is probably a correct statement. I have 2 messages with a single
envelope. Technically, this is exactly what I'm doing.

Anyways, I'm working up implementing the DataContractSerlializer and
will contribute it back should it work well. My question then is
still: how do I get this plugged into the MsmqEndpoint to use? Is
there a special key in my IoC container to register this serializer
under such that automatic resolution of MsmqEndpoints will take a
different serializer?

On Nov 22, 6:57 am, Dru Sellers <d...@drusellers.com> wrote:
> One thing to be careful of is this statement.
>
> "chose the natural object -oriented approach (inheritance) rather than ..."
>
> I hadn't really thought much about it, and I am not really sure either, but
> I bet that the design of a message shouldn't be thought of as 'object-y'.
> objects have behaviour and messages do not.
>
> So, what are we to do? Not knowing your model and what the differences are,
> I offer the following:
>
> instead of inheritance, try composition. is your message really two messages
> that need to be sent in one 'envelope'?
>
> -d
>
> > masstransit-dis...@googlegroups.com<masstransit-discuss%2Bunsu bsc...@googlegroups.com>
> > .
> > > >>> For more options, visit this group athttp://
> > groups.google.com/group/masstransit-discuss?hl=.
>
> > > >> Chris Patterson
> > > >> chrisfromtu...@gmail.com
>
> > > > --
>
> > > > 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<masstransit-discuss%2Bunsu bsc...@googlegroups.com>
> > .
> > > > For more options, visit this group athttp://
> > groups.google.com/group/masstransit-discuss?hl=.
>
> > > Chris Patterson
> > > chrisfromtu...@gmail.com
>
> > --
>
> > 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<masstransit-discuss%2Bunsu bsc...@googlegroups.com>
> > .

Rob Tennyson

unread,
Nov 22, 2009, 7:30:34 PM11/22/09
to masstransit-discuss
If it helps, this is how I'm setting the serializer for my command
pattern implementation...

public class SpikeRegistry : MassTransitRegistryBase
{
//private readonly string _uri = "msmq://whqwppsqa01/mt-spike?
tx=true";
private readonly string _uri = "msmq://localhost/mt-spike?
tx=true";

public SpikeRegistry()
{
MsmqEndpointConfigurator.Defaults(config =>
config.CreateMissingQueues = true);

RegisterEndpointFactory(x =>
{
x.RegisterTransport<MsmqEndpoint>();
x.SetDefaultSerializer<BinaryMessageSerializer>();
});

RegisterServiceBus(
_uri,
x => x.ConfigureService<RoutingConfigurator>(config =>
config.Route<ICommand>().To(_uri)));

craiggwilson

unread,
Nov 22, 2009, 7:42:53 PM11/22/09
to masstransit-discuss
EndpointFactoryConfigurator... thanks Rob. I've been looking all over
for that.
> ...
>
> read more »
Reply all
Reply to author
Forward
0 new messages