In this new project I'm working on I need to create objects on runtime by data from the DB, right now I have two groups of classes, each group implementing a different interface.
I started working on a factory class, which will map id to a type, an abstract one so I can extend with a factory for each group.
The constructor parameter is the type of the interface common to all implementors of the group.
abstract class Factory { private Dictionary<int, Type> idsToTypes; private Type type; public Factory(Type _type) { idsToTypes = new Dictionary<int, Type>(); type = _type; } protected Object GetProduct(int id, params object[] args) { if (idsToTypes.ContainsKey(id)) { return Activator.CreateInstance(idsToTypes[id], args); } else { return null; } } public void RegisterProductType(int id, Type _type) { if (_type.IsInterface || _type.IsAbstract) throw new ArgumentException(String.Format("Registered type, {0}, is interface or abstract and cannot be registered",_type)); if (type.IsAssignableFrom(_type)) { idsToTypes.Add(id, _type); } else { throw new ArgumentException(String.Format("Registered type, {0}, was not assignable from {1}",_type,type)); } }
Then I noticed both extending factories look the same, and in the end with the use of generics I got to this class:
class GenericSingletonFactory<T> : Factory { static public GenericSingletonFactory<T> Instance = new GenericSingletonFactory<T>(); private GenericSingletonFactory() : base(typeof(T)) { } public T GetObject(int id, params object[] args) { Object obj = base.GetProduct(id, args); if (obj != null) { T product = (T)obj; return product; } else return default(T); } }
So I can just use like so:
GenericSingletonFactory<ISomething>.Instance.RegisterProductType(1, typeof(ImplementingISomething)); ISomething something = GenericSingletonFactory<ISomething>.Instance.GetObject(1);
It seems ok... but am I missing something here? is this a good way to do this kind of things? I'm a little weary that this will fall apart on runtime somehow...