views:

276

answers:

1

Hello!

I have about 20 classes for different messages and this number are growing. Each class has a unique ID, so I can transform the class on a byte[] with my own method of serialization and then transform a byte[] again on my class with this uniqueID. All my messages are children of a BaseMessage class that already implements the uniqueID generation correctly.

What I want to do is direct find the class of a respective ID without using a Enum to compare. My problem with the Enum is that Enums are not auto updated with my new IDs every time I create a new message class.

There a way to combine Attributes and Assembly to do this, Like discovering all children of BaseClass and then call for a CustomAtributte?

Thank you!

+2  A: 

You're on the right path - that does sound like a good way to handle it. You'll want to store the unique ID of the type alongside the serialized value, so you can read the ID before deserialization, to direct the deserializer to the correct type. You could also just store the fully qualified type name instead of using an ID, but this is a fine approach too.

The attribute is simple enough to create:

class MessageAttribute : Attribute
{
    public Guid ID; //assuming you want to use a GUID, could be anything
}

And using it is also simple:

[Message(ID = new Guid("..."))]
class SubMessage : BaseMessage
{
}

You can load all the types in a given assembly and iterate over them very quickly:

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);
        }
    }
}
Rex M
Thank you for this very fast answer.Are you sure this assembly loading and type looping are quickly? I need do to this verification a lot of times on my program. I think I can create this list on a static time and just use after that.
Gustavo Cardoso
@Gustavo yes, it is quite fast. You are correct of course that it only needs to be done once at startup anyway. The list can be cached for the life of the app after that.
Rex M