5

Going on with my quest to bend protobuf-net to my own will..

I've seen a few questions around SO on how to add sub-classes dynamically for the serializer to be able to encode the sub-class.., like this or this

My situation is bit different, I have a base class that might get sub-classed in late-bounded code, and I want to serialize is as the BASE class, and completely ignore the sub-class's fields/properties.

The reason I need this, is that later on, when I deserialize the data, the sub-class's code will not be even available, so constructing the sub-class will not be even possible.

Is there a way to limit/prohibit sub-class serializtion?

In my case I have a List where some items in the list are DerivedClass.

I would like to find a way to make protobuf-net serialize everything as BaseClass and to deserialize to BaseClass as well...

I've tried peering into code, but haven't found something too useful.

Community
  • 1
  • 1
damageboy
  • 2,097
  • 19
  • 34

1 Answers1

2

Normally, the library is very particular about spotting derived classes - and treating them differently from the base class. The only current exception to that is proxy classes, in particular Entity Framework and NHibernate. For a tidy solution, it would seem practical to add some kind of "ignore subclasses" switch. But while that doesn't exist, a very lazy (and hacky) approach would be to cheat using the existing handling for NHibernate, for example:

namespace NHibernate.Proxy {
    interface INHibernateProxy {}
}
...
public class SomeDerivedType : BaseType, INHibernateProxy {}

this will then automatically be serialized as per BaseType. It does have a faint whiff of cheating about it, though.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Faint whiff you say? ;) I think I'll hack into the source Coe but thanks for the suggestion – damageboy Oct 04 '11 at 06:19
  • 1
    @damageboy if you wanted to add some custom mechanism for this, `TypeModel.ResolveProxies` would be worth looking at. I'm not against adding a protobuf-net specific API here. – Marc Gravell Oct 04 '11 at 06:20
  • Just so we are in the clear here... The reason you are pointing me towards ResolveProxies is because it is called from ThrowUnexpectedSubtype as last resort before throwing the exception? – damageboy Oct 04 '11 at 08:59
  • @damageboy there are, IIRC, a *number* of places (not just `ThrowUnexpectedSubtype`) that use that method as a second-chance - most importantly `TypeModel.GetKey` (which is how it chooses a strategy from a `Type`) and `FindOrAddAuto` / `FindWithoutAdd`. – Marc Gravell Oct 04 '11 at 10:01
  • Hi Marc, I ended up adding a property on the MetaType: "FlattenUnexpectedSubtypes" which ultimately changes the code generator's emitted IL according to the presence of this flag... Seems to work fine... I've tried sending you a patch a couple of days ago for some other feature but didn't get any response from you... if e-mail a preferred method of communicating for patches? – damageboy Oct 04 '11 at 13:57
  • @damageboy no offence was intended; my inbox is a wild and dangerous place... I'll check later – Marc Gravell Oct 04 '11 at 14:05
  • 2
    @MarcGravell Did this ever get patched in? I need this functionality. – David Pfeffer Jan 31 '12 at 13:11
  • @MarcGravell Did this ever make it in somewhere? Or is there a new way to do this in v2? – Jeremy Seekamp Apr 25 '13 at 04:21