Dynamic class creation

M

Mark Sisson

I'd like to instantiate a variable but the exact class is not known at
compile time. In my specific application, I'm reading a message off
of an socket and interogating the first part of the message (with a
messageTypeId). Based on that messageTypeId I'd like to instantiate
the appropriate class.

I've started the method below but I'm wondering if there's a way to do
this without creating a huge switch statement. Any ideas??

TIA



public static AppMessage GetMessage(string MessageString)
{
AppMessage rslt = null;
try
{
AppMessageType mt =
(AppMessageType)(Convert.ToInt32(MessageString.Substring(0, 3)));

switch (mt)
{
case AppMessageType.LoginRequest:
rslt = new MsgLoginRequest(MessageString);
break;
case AppMessageType.LoginResponse:
rslt = new MsgLoginResponse(MessageString);
break;
case AppMessageType.AssignTable:
rslt = new MsgAssignTable(MessageString);
break;
default:
rslt = null;
break;
}
}
catch (Exception e)
{
//TODO:exception
}
return rslt;
}
 
N

Nicholas Paldino [.NET/C# MVP]

Mark,

If all of the types have parameterless constructors, then I would do the
following. First, I would create a static Hashtable (or a Dictionary<K, V>
in .NET 2.0, where K is AppMessageType and V is Type). Once you have that,
I would create a static constructor which would populate this hash table,
with the key being the values from the AppMessageType enumeration, and the
values being the Type that represents the type of object they map to. If
you wanted to get really fancy, you could create an attribute that you
attach to each value in the enumeration, and get reflection to get them (in
which case, you don't need the hash table).

Once you have that, you just have to do a lookup for the type, and then
call the static CreateInstance method on the Activator class, passing in the
Type that is returned from the lookup.

Hope this helps.
 
J

John Murray

Before I type this, I am not recommending this approach as being better
than a switch -- depending on the number of cases you expect, a switch
may be the appropriate answer. If you have a large number of checks,
some combination of a chain of control or prototype factory might be
easier to maintain.

For example, if you have a factor class that returns an AppMessage
object on a call to the static Process method. When it is called, it
maintains an internal collection of instances of your objects derived
from AppMessage (MsgLoginRequest,MsgLoginResponse ..etc..) and walks
through each object in the collection asking it if it knows how to
handle the AppMessageType that you pass in. If the object does know how
to handle the message it could either return a reference to the instance
from the factory -- or it could clone the instance in the factory and
return a unique instance (depending on your requirements.)

This approach encapsulates the logic of which class can handle which
message directly into the class that handles that message.

John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top