Description
There are times when it would be nice to include a simple POCO style type in an object graph. Right now the most basic serializable type is MobileObject
, which requires manual work to serialize things like fields.
There are several thoughts to consider. One is documented here, which is to use a base class. Another would be to have MF trigger on an attribute that delegates to an arbitrary "serializer" that returns/accepts a byte[]
representing that class. Yet another would be to pass in a list of serializers to MobileFormatter (via DI), where each of these serializers would have the opportunity to say that they can serialize a given type that would otherwise not be serialized by MF.
MobilePoco base class
It is possible to create a MobilePoco
type that uses reflection to get/set property and field values as needed by the MobileFormatter. This should be added to the Csla.Core namespace.
Here's a quick prototype of the idea:
using System;
using Csla.Serialization.Mobile;
namespace ConsoleApp3
{
[Serializable]
public abstract class MobilePoco : IMobileObject
{
void IMobileObject.GetChildren(SerializationInfo info, MobileFormatter formatter)
{
}
void IMobileObject.SetChildren(SerializationInfo info, MobileFormatter formatter)
{
}
private const System.Reflection.BindingFlags bindingFlags =
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance;
void IMobileObject.GetState(SerializationInfo info)
{
var fields = this.GetType().GetFields(bindingFlags);
foreach (var item in fields)
info.AddValue(item.Name, item.GetValue(this));
var properties = this.GetType().GetProperties(bindingFlags);
foreach (var item in properties)
info.AddValue(item.Name, item.GetValue(this));
}
void IMobileObject.SetState(SerializationInfo info)
{
var fields = this.GetType().GetFields(bindingFlags);
foreach (var item in fields)
item.SetValue(this, info.GetValue<object>(item.Name));
var properties = this.GetType().GetProperties(bindingFlags);
foreach (var item in properties)
item.SetValue(this, info.GetValue<object>(item.Name));
}
}
}
SerializeUsing attribute
[SerializeUsing(typeof(MySerializer))]
public class MyPoco {}
Presumably the MySerializer
type would implement Csla.Serialization.ISerializationFormatter
.
Custom Serializer List
Regarding the DI injection of a list of serializers, those serializers might implement an interface like this:
public interface ISerializer
{
bool SerializesType(Type type);
byte[] Serialize(object obj);
object Deserialize(byte[] data);
}
When MF encounters a type it wouldn't otherwise be able to serialize, it would go through the list of custom serializers, calling SerializesType
on each. If one returns true
, then it would be used to serialize the object in question.
This technique could be used to generalize the way ClaimsPrincipal
is currently handled. Right now it is hard-coded into MF as an exception, but that implementation could be moved out to a custom serializer instead.