Skip to content

Instantly share code, notes, and snippets.

@devoyster
Created December 13, 2011 21:24
Show Gist options
  • Save devoyster/1473960 to your computer and use it in GitHub Desktop.
Save devoyster/1473960 to your computer and use it in GitHub Desktop.
protobuf-net registering type at runtime
var model = RuntimeTypeModel.Default;
// Obtain all serializable types having no explicit proto contract
var serializableTypes = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => t.IsSerializable && !Attribute.IsDefined(t, typeof(ProtoContractAttribute)));
foreach (var type in serializableTypes)
{
var metaType = model.Add(type, false);
metaType.AsReferenceDefault = true;
metaType.UseConstructor = false;
// Add contract for all the serializable fields
var serializableFields = type
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Where(fi => !Attribute.IsDefined(fi, typeof(NonSerializedAttribute)))
.OrderBy(fi => fi.Name) // it's important to keep the same fields order in all the AppDomains
.Select((fi, index) => new { info = fi, index });
foreach (var field in serializableFields)
{
var metaField = metaType.AddField(field.index + 1, field.info.Name);
metaField.AsReference = !field.info.FieldType.IsValueType; // cyclic references support
metaField.DynamicType = field.info.FieldType == typeof(object); // any type support
}
}
// Compile model in place for better performance, .Compile() can be used if all types are known beforehand
model.CompileInPlace();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment