感谢@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
转换为适当的类型以使注册工作(并调用适当的注册表?
更新:我想通了
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 });
}
}
答案 0 :(得分:3)
您需要使用反射调用Register
,如下所示:
typeof(Locator)
.GetMethod("Register")
.MakeGenericMethod(type)
.Invoke(null, manager);