Вы на правильном пути - это действительно хороший способ справиться с этим. Вы захотите сохранить уникальный идентификатор типа вместе с сериализованным значением, чтобы вы могли прочитать идентификатор перед десериализацией, чтобы направить десериализатор к правильному типу. Вы также можете просто сохранить полное имя типа вместо использования идентификатора, но это тоже хороший подход.
Атрибут достаточно прост для создания:
class MessageAttribute : Attribute
{
public Guid ID; //assuming you want to use a GUID, could be anything
}
И использовать это также просто:
[Message(ID = new Guid("..."))]
class SubMessage : BaseMessage
{
}
Вы можете загрузить все типы в данной сборке и очень быстро их перебрать:
List<Type> messageTypes = new List<Type>();
//get the assembly containing our types
Assembly messageAssembly = Assembly.Load(...);
//get all the types in the assembly
Type[] types = messageAssembly.GetTypes();
foreach(Type type in types)
{
//make sure we inherit from BaseMessage
if(type.IsAssignableFrom(typeof(BaseMessage))
{
//check to see if the inherited type has a MessageAttribute
object[] attribs = type.GetCustomAttribtues(typeof(MessageAttribute), true);
if(attribs.Length > 0)
{
messageTypes.Add(type);
}
}
}