Thanks @dtb for help, he advised really need piece of code for generic service locator
static class Locator
{
private static class LocatorEntry<T> where T : ...
{
public static IDataManager<T> instance;
}
public static void Register<T>(IDataManager<T> instance) where T : ...
{
LocatorEntry<T>.instance = instance;
}
public static IDataManager<T> GetInstance<T>() where T : ...
{
return LocatorEntry<T>.instance;
}
}
However in my previous version I used reflection on assembly to discover a hundred of DataManager's
I want to write an method discover like the following
void Discover()
{
var pManager = new ProtocolSQLDataManager();
Register(pManager);
var rManager = new ResultSQLDataManager();
Register(rManager);
var gType = typeof(ISQLDataAccessManager<>);
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
if (type.IsSubclassOf(gType) && !type.IsAbstract))
{
var manager = Activator.CreateInstance(type);
// put something here in order to make next line of code works
Register<T>(manager);
}
}
}
How to cast type
to appropriate type in order to make Register working( and call appropriate Register ?
UPDATE: I figured it out
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
if ( type.GetInterface("IDataAccessManager`1") != null && !type.IsAbstract)
{
var manager = Activator.CreateInstance(type);
var t = type.GetInterface("IDataAccessManager`1").GetGenericArguments()[0];
typeof(GenLocator)
.GetMethod("Register")
.MakeGenericMethod(t)
.Invoke(null, new[] { manager });
}
}