Спасибо @dtb за помощь, он посоветовал действительно нужен кусок кода для универсального локатора службы
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;
}
}
Однако в моей предыдущей версии я использовал отражение в сборке, чтобы обнаружить сотню DataManager
Я хочу написать метод обнаружения, подобный следующему
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);
}
}
}
Как привести type
к соответствующему типу, чтобы заставить Регистр работать (и вызвать соответствующий Регистр?
ОБНОВЛЕНИЕ: Iпонял это
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 });
}
}