Take the 2-minute tour ×

I have a request to read string messages from a queue and "process them". Each message has a 4 digit "identifier/key" a the start, followed by date, time and another number...from then on, each message is different and requires different processing.

My thought was to use a factory to create an object of the required type and ALSO call the asbtract constructor at the same time.

Is this a sensible approach to take?
If so...how?



To build object of classes

Message1000 : AbstractMessage, IMessageThing
Message4000 : AbstractMessage, IMessageThing
Message4003 : AbstractMessage, IMessageThing

Where AbstractMessage contains a default constructor and properties for key, date, time, number etc.

share|improve this question
add comment

4 Answers

up vote 1 down vote accepted

If it makes sense depends on your requirements.

You could analyse the string like this:

// inside your actual factoryMethod...
var lines = ...;

foreach(var line in lines)
    var tokens = line.Split(',');
    // for split: you can also specify the max. amount of items if the ..... part can
    // consist of more the dots.

    CreateMessageObject(tokens); // eventually add to list of AbstractMessage or whatever

static FactoryClassConstructor()
     _typeMap = new Dictionary<string, Type>();
     _typeMap.Add("Message1000", typeof(Message1000));
     // todo: add other message types
     // you also could write a method which will use the class name of the 
     // type returned by typeof(XYZ) to assure the correct value as key

private Dictionary<string, Type> _typeMap;

private AbstractMessage CreateMessageObject(string[] tokens)
    // simple error checking
    if(tokens.Count != 5)
        // todo: error handling
        return null;

    var type = typeMap[tokens[0]];
    var instance = Activator.CreateInstance(type);

    instance.Date = DateTime.Parse(tokens[1]);
    instance.Time = DateTime.Parse(tokens[2]);
    // todo initialize other properties

Of course you still need to do some error handling but I hope I could give you a good starting point.

The reason why i would use a dictionary is performance. Activator.CreateInstance is not very fast and the lookup with Type.GetType is also slow. Instead of using the type as Value in the Dictionary you could also use something like this:

Dictionary<string, Action<IMessageThing>> _factories;
_factories = new Dictionary<string, Action<IMessageThing>>();
_factories.Add("Message1000", () => new Message1000());

and to create your object you could call:

var instance = _factories["Message1000"]();
share|improve this answer
I like this way - changed it to Func<string, IMessageThing> and _factories.Add("Message1000",(message)=>new Message1000(message)); to get the base constructor called too :) –  BlueChippy Feb 13 '13 at 12:03
add comment

You can either pass each message to a handler, the handler will check if it can handle this type of message. If so it will parse and return some object, otherwise it will return e.g. null and you will know to ask a different handler.

Or you build a parser that knows about the initial part that follows a common format, and then use a lookup table to find a specific message handler that will parse the remaining message and instantiate the correct type. (Pass the common parts to its constructor).

I don't understand what you mean with "create an object of the required type and ALSO call the asbtract constructor". There is no such thing as an abstract constructor. If you mean a constructor of an abstract base class, it is inevitable that it will get called when a subclass is instantiated.

share|improve this answer
add comment

One way is to split the string on , but set the max count to say 5, this should group all the values AFTER the number as one value:

var parts = your_string.split(new char[] {','},5);

Then you just need to use Activator.CreateInstance() to create your message instance. For example:

Type type = Type.GetType(String.Format("Message{0}",parts[0]));
var instance = Activator.CreateInstance(type) as IMessageThing;

You can then fill out the rest of the properties from parts.

share|improve this answer
add comment

Yes you can and is a correct and sensible approach. The things change a little if you can have a default constructor or not, and changes too if constructor will differ from one concrete implementation to the other. The simplest approach is to have a parameterless constructor. With this prerequisite you can have something like this:

Type t = Type.GetType(string.Format("Handlers.MyHandlers.Message{0}",messageType));
var handler = Activator.CreateInstance(t) as IMessageThing;

In order to pass the string to the message, you can have a function defined in the IMessageThing interface, lets call it Init that you call immediately after the message creation, or probably better, have a costructor taking a string in the AbstractMessage class, and call it in the activator like this:

var handler = Activator.CreateInstance(t,body) as IMessageThing;

In the constructor of AbstractMessage call an abstract function Init(string body), so each concrete message need to implement its own parser.

Add some more error handling, and you have done.

share|improve this answer
add comment

Your Answer


