我有一个应用程序,我想在config中定义消息队列。所以我想在config中指定一些消息类型,例如“app.msg.UpdateMsg”或“app.msg.SnapshotMsg”,以便为其创建队列。
假设我的消息队列类看起来像这样:
public class MsgQueue<T> : where T: MsgBase, new()
{
private readonly Action<T> _queueListener;
public MsgQueue(Action<T> queueListener)
{
_queueListener = queueListener;
}
...
}
现在假设我有另一个想要从配置中读取其中列出的队列类型的类,并将它们放入容器中。像这样:
public class QueueManager
{
// We know T is a MsgBase, but not much else :(
private List<MsgQueue<MsgBase>> _msgQueues = new List<MsgQueue<MsgBase>>();
public QueueManager()
{
List<string> configuredQueueTypes = GetQueueTypesFromConfig();
PopulateMsgQueues(configuredQueueTypes);
}
private void PopulateMsgQueues(List<string> qTypes)
{
foreach (string qType in qTypes)
{
Action<MsgBase> listener = GetListener(qType);
// What goes here? How do I create a MsgQueue<qType>?
}
}
...
}
如果可能,我该如何定义PopulateMsgQueues()?
如果我可以在配置中指定“app.MsgQueue of app.msg.UpdateMsg”这样的话,是否可能(并且会有所帮助)?
有没有人知道任何其他方法来实例化一堆T的MsgQueue,其中T在运行时由字符串指定?
我正在使用C#4.0,动态关键字可以帮助我吗?
谢谢!
答案 0 :(得分:1)
您可以使用Type.GetType(string)
然后使用它来实例化您的泛型类。
例如,这将实例化一个字符串列表:
Type type = typeof(List<>).MakeGenericType(Type.GetType("String"));
Activator.CreateInstance(type);
答案 1 :(得分:0)
我不认为动态在这里很好。你需要诉诸旧的反思。
答案 2 :(得分:0)
这是不可能的,因为类型需要在编译时知道,而不是运行时。
你可以使用反射,但是你失去了强类型并且有一个性能损失(对你来说可能或不重要)
Action<MsgBase> listener = GetListener(qType);
Type type = typeof(MsgQueue<>).MakeGenericType(Type.GetType("String"));
dynamic msgQueue = Activator.CreateInstance(type, listener);
//do whatever with msgQueue.