I have a Dictionary to map a certain type to a certain generic object for that type. For example:
typeof(LoginMessage) maps to MessageProcessor
I struggled to solve a similar problem around data table classes instead of messages. The root issue mentioned above of casting a non-generic version of the class to a derived generic version was the same.
In order to allow injection into a portable class library which did not support database libraries, I introduced a set of interface classes, with the intent that I could pass a type and get a matching generic. It ended up needing to implement a generic method.
// Interface for injection
public interface IDatabase
{
// Original, non-functional signature:
IDatatable
And this the whole implementation using the generic method above.
The generic class that will be cast from a dictionary.
// Non-generic base class allows listing tables together
abstract class Datatable
{
Datatable(Type storedClass)
{
StoredClass = storedClass;
}
Type StoredClass { get; private set; }
}
// Generic inheriting class
abstract class Datatable: Datatable, IDatatable
{
protected Datatable()
:base(typeof(T))
{
}
}
This is the class that stores the generic class and casts it to satisfy the generic method in the interface
class Database
{
// Dictionary storing the classes using the non-generic base class
private Dictionary _tableDictionary;
protected Database(List tables)
{
_tableDictionary = new Dictionary();
foreach (var table in tables)
{
_tableDictionary.Add(table.StoredClass, table);
}
}
// Interface implementation, casts the generic
public IDatatable GetDataTable()
{
Datatable table = null;
_tableDictionary.TryGetValue(typeof(T), out table);
return table as IDatatable;
}
}
And finally the calling of the interface method.
IDatatable table = _database.GetDataTable();