Dynamic class creation

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Mark Sisson

    Dynamic class creation

    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(stri ng MessageString)
    {
    AppMessage rslt = null;
    try
    {
    AppMessageType mt =
    (AppMessageType )(Convert.ToInt 32(MessageStrin g.Substring(0, 3)));

    switch (mt)
    {
    case AppMessageType. LoginRequest:
    rslt = new MsgLoginRequest (MessageString) ;
    break;
    case AppMessageType. LoginResponse:
    rslt = new MsgLoginRespons e(MessageString );
    break;
    case AppMessageType. AssignTable:
    rslt = new MsgAssignTable( MessageString);
    break;
    default:
    rslt = null;
    break;
    }
    }
    catch (Exception e)
    {
    //TODO:exception
    }
    return rslt;
    }
  • Nicholas Paldino [.NET/C# MVP]

    #2
    Re: Dynamic class creation

    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.


    --
    - Nicholas Paldino [.NET/C# MVP]
    - mvp@spam.guard. caspershouse.co m

    "Mark Sisson" <mark@corporate digital.com> wrote in message
    news:88cc4eb9.0 410150603.7fe00 597@posting.goo gle.com...[color=blue]
    > 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(stri ng MessageString)
    > {
    > AppMessage rslt = null;
    > try
    > {
    > AppMessageType mt =
    > (AppMessageType )(Convert.ToInt 32(MessageStrin g.Substring(0, 3)));
    >
    > switch (mt)
    > {
    > case AppMessageType. LoginRequest:
    > rslt = new MsgLoginRequest (MessageString) ;
    > break;
    > case AppMessageType. LoginResponse:
    > rslt = new MsgLoginRespons e(MessageString );
    > break;
    > case AppMessageType. AssignTable:
    > rslt = new MsgAssignTable( MessageString);
    > break;
    > default:
    > rslt = null;
    > break;
    > }
    > }
    > catch (Exception e)
    > {
    > //TODO:exception
    > }
    > return rslt;
    > }[/color]


    Comment

    • John Murray

      #3
      Re: Dynamic class creation

      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 (MsgLoginReques t,MsgLoginRespo nse ..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



      Mark Sisson wrote:[color=blue]
      > 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(stri ng MessageString)
      > {
      > AppMessage rslt = null;
      > try
      > {
      > AppMessageType mt =
      > (AppMessageType )(Convert.ToInt 32(MessageStrin g.Substring(0, 3)));
      >
      > switch (mt)
      > {
      > case AppMessageType. LoginRequest:
      > rslt = new MsgLoginRequest (MessageString) ;
      > break;
      > case AppMessageType. LoginResponse:
      > rslt = new MsgLoginRespons e(MessageString );
      > break;
      > case AppMessageType. AssignTable:
      > rslt = new MsgAssignTable( MessageString);
      > break;
      > default:
      > rslt = null;
      > break;
      > }
      > }
      > catch (Exception e)
      > {
      > //TODO:exception
      > }
      > return rslt;
      > }[/color]

      Comment

      Working...