Thanks for the help Marc, I ended up writing an app to generate a report of the ordering ProtoBuf was using, then going any applying that order to each property and removing the ProtoContract from everything.
Code may be useful to others in the future, so here it is as a starting point (need to tweak it to create the original first then do the compare and generate report).
Cheers.
Ross.
public class Program
{
static void Main(string[] args)
{
var original = Console.Out;
Console.WriteLine("Outputting Report to file");
using (var stream = new StreamWriter("Report.txt"))
{
Console.SetOut(stream);
ISerializer serializer = new ProtobufSerializer(); // custom implementation class
var toCheck = LoadOriginal();
Console.WriteLine("Loaded OK");
foreach (var item in toCheck.Types)
{
Console.WriteLine("Processing Type [{0}]", item.Name);
var type = Type.GetType(item.Type);
if (type == null)
{
Console.WriteLine("ERROR LOADING TYPE!");
throw new Exception("Why?");
}
var ca = type.GetCustomAttributes(typeof(ProtoContractAttribute), false);
if (ca.Length > 0)
{
Console.WriteLine(
"\t*** WARNING: TYPE IS USING ProtoContractAttribute! This should be fixed. ***");
}
if(type.IsEnum)
{
Console.WriteLine("Enum - Ignoring order check.");
}
else
{
foreach (var field in item.Feilds)
{
PropertyInfo pi = type.GetProperty(field.Name,
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance);
Console.Write("\t[{0}]\t\tExpected [{1}]\t\t", field.Name, field.Order);
if (pi == null)
{
Console.Write("ERROR - PROPERTY MISSING!");
}
else
{
var attributes = pi.GetCustomAttributes(typeof(DataMemberAttribute), false);
if (attributes.Length == 0)
{
Console.Write("ERROR! DataMember Attribute not found.");
}
else if (attributes.Length > 1)
{
Console.Write("ERROR! Expecting one DataMember Attribute.");
}
else
{
var attr = attributes[0] as DataMemberAttribute;
if (attr.Order == field.Order)
{
Console.Write("OK");
}
else
{
Console.Write("ERROR! Incorrect order [{0}]", attr.Order);
}
}
}
Console.WriteLine();
}
}
Console.WriteLine();
}
stream.Flush();
}
Console.SetOut(original);
Console.WriteLine("Done.");
Console.ReadKey();
}
private static CompatabilityOrder LoadOriginal()
{
if (File.Exists("Original.xml"))
{
XmlSerializer s = new XmlSerializer(typeof(CompatabilityOrder));
return s.Deserialize(File.Open("Original.xml", FileMode.Open)) as CompatabilityOrder;
}
else
{
return new CompatabilityOrder();
}
}
private static CompatabilityOrder GenerateOriginal()
{
var x = ProtoBuf.Meta.RuntimeTypeModel.Default;
List<ProtoBuf.Meta.MetaType> mt = new List<MetaType>();
mt.AddRange(x.GetTypes().OfType<ProtoBuf.Meta.MetaType>());
// loop around and find any types that have the attribute ProtoContract on them
// and add them to the collection
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (Type t in a.GetTypes())
{
if (t.GetCustomAttributes(typeof(ProtoContractAttribute), false).Any())
{
mt.Add(x.Add(t, true));
}
}
}
CompatabilityOrder co = LoadOriginal(); // build on what we have
foreach (ProtoBuf.Meta.MetaType metaType in mt)
{
if (!co.Types.Any(t => t.Type == metaType.Type.AssemblyQualifiedName))
{
var cot = new CompatabilityOrderType();
cot.Name = metaType.ToString();
cot.Type = metaType.Type.AssemblyQualifiedName;
cot.Feilds = new List<CompatabiltityOrderTypeField>();
foreach (var member in metaType.GetFields())
{
cot.Feilds.Add(new CompatabiltityOrderTypeField() { Name = member.Name, Order = member.FieldNumber });
}
co.Types.Add(cot);
}
}
XmlSerializer s = new XmlSerializer(co.GetType());
var fs = File.Create("Original.xml");
s.Serialize(fs, co);
return co;
}
public class CompatabilityOrder
{
public List<CompatabilityOrderType> Types = new List<CompatabilityOrderType>();
}
public class CompatabilityOrderType
{