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...