Reputation: 1459
I use surrogates and I'd like to perform a check to skip wrong items during the serialization process, but I can't find a way to do it, any idea?
BeforeSerialize method is called after the creation of the surrogate and I'd like to know how to skip items that have no the requirements specified in the protoBuf serialization context.
Here following, a sample code to reproduce my scenario.
public class Person
{
public Person(string name, GenderType gender)
{
Name = name;
Gender = gender;
}
public string Name { get; set; }
public GenderType Gender { get; set; }
}
public class PersonSurrogate
{
public string Name { get; set; }
public byte Gender { get; set; }
public PersonSurrogate(string name, byte gender)
{
Name = name;
Gender = gender;
}
protected virtual bool CheckSurrogateData(GenderType gender)
{
return gender == GenderType.Both || (GenderType)Gender == gender;
}
#region Static Methods
public static implicit operator Person(PersonSurrogate surrogate)
{
if (surrogate == null) return null;
return new Person(surrogate.Name, (GenderType)surrogate.Gender);
}
public static implicit operator PersonSurrogate(Person source)
{
return source == null ? null : new PersonSurrogate(source.Name, (byte)source.Gender);
}
#endregion
protected virtual void BeforeSerialize(ProtoBuf.SerializationContext serializationContext)
{
var serializer = serializationContext.Context as FamilySerializer;
if (serializer == null)
throw new ArgumentException("Serialization context does not contain a valid Serializer object.");
if (!CheckSurrogateData(serializer.GenderToInclude))
{
// ** How can I exclude this item from the serialization ? **//
}
}
}
[Flags]
public enum GenderType : byte
{
Male = 1,
Female = 2,
Both = Male | Female
}
/// <summary>
/// Class with model for protobuf serialization
/// </summary>
public class FamilySerializer
{
public GenderType GenderToInclude;
public RuntimeTypeModel Model { get; protected set; }
protected virtual void FillModel()
{
Model = RuntimeTypeModel.Create();
Model.Add(typeof(Family), false)
.SetSurrogate(typeof(FamilySurrogate));
Model[typeof(FamilySurrogate)]
.Add(1, "People") // This is a list of Person of course
.UseConstructor = false;
Model.Add(typeof(Person), false)
.SetSurrogate(typeof(PersonSurrogate));
MetaType mt = Model[typeof(PersonSurrogate)]
.Add(1, "Name")
.Add(2, "Gender");
mt.SetCallbacks("BeforeSerialize", null, null, null); // I'd like to check surrogate data and skip some items - how can I do?
mt.UseConstructor = false; // Avoids to use the parameterless constructor.
}
}
Upvotes: 2
Views: 399
Reputation: 1064104
What you describe is not a scenario that the serializer currently makes any attempt to target. Conditional serialization is supported on a per-property/field basis, but not on a per object basis.
There might still be ways to get it to work, though - but it depends on what the context is, i.e. what is it that has a Person
object in your model? And can you change that model at all? (possibly not, since you're using surrogates).
My default answer, as soon as things stop working cleanly, is to say: create a separate DTO model for your serialization work, and populate that with the data that you intend to serialize - rather than fighting to get your regular domain model to play nicely with complex serialization requirements.
Upvotes: 2