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?
e.g.
1000,2013-02-13,09:00:00,492,....................
4000,2013-02-13,09:00:01,492,....................
1000,2013-02-13,09:00:02,74664,....................
4003,2013-02-13,09:00:03,1010,....................
4000,2013-02-13,09:00:04,493,....................
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.
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"]();