如何在运行时决定将哪种类型作为泛型参数传递?
我有几个消息队列,其中包含特定的消息。 我使用 xsd.exe 为这些消息创建了类。 我可以同步接收消息并使用此方法反序列化它:
public oneOfMyTypes DeserializeMessage(XDocument message)
{
var serializer = new XmlSerializer(typeof(oneOfMyTypes));
var entity = (oneOfMyTypes)serializer.Deserialize(message.CreateReader());
return entity;
}
然后我通过 Fluent NHibernate 持久化该实体。
所以我有大约五个消息队列,它们都有自己的消息类型。 我希望保持这个小处理器应用程序的可维护性,以便添加更多消息队列和消息类型不会变得很痛苦。
因此,我的 app.config 中有一个队列名称列表,用于在启动时创建消息队列,然后我想将单个方法连接到所有队列的 .ReceiveCompleted 事件:
void queue_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
var queue = (MessageQueue)sender;
var message = queue.EndReceive(e.AsyncResult);
var body = message.Body.ToString();
var xml = XDocument.Parse(body);
var queueName = queue.QueueName;
Type entityType = GetTypeFromQueueName(queueName);
entityType entity = DeserializeMessage<entityType>(xml);
var repository = new LogRepository();
repository.AddEntity<entityType>(entity);
}
private T DeserializeMessage<T>(XDocument message)
{
var serializer = new XmlSerializer(typeof(T));
var entity = (T)serializer.Deserialize(message.CreateReader());
return entity;
}
public Type GetTypeFromQueueName(string queueName)
{
switch (queueName)
{
case "some-message-queue-name":
return typeof (oneOfMyTypes);
}
}
但是当我尝试传递实体类型时对于通用方法,我得到“预期的类型或命名空间名称”。 我可能正在做一些非常愚蠢的事情,但我不知道这应该如何运作。
我尝试过使用dynamic关键字和.MakeGenericType,但没有成功。 我还查看了:
但我仍然没有得到它......帮助?
I have several message queues that have specific messages on them.
I've created classes for these messages using xsd.exe.
I can receive a message syncronously and deseriazlise it with this method:
public oneOfMyTypes DeserializeMessage(XDocument message)
{
var serializer = new XmlSerializer(typeof(oneOfMyTypes));
var entity = (oneOfMyTypes)serializer.Deserialize(message.CreateReader());
return entity;
}
I then persist the entity via Fluent NHibernate.
So I've got about five message queues that all have their own type of message.
I would like to keep this little processor app maintainable, so that adding more message queues and message types doesn't become a pain.
So I have a list of queue names in my app.config that I use to create the message queues on start up and then I want to wire up a single method to the .ReceiveCompleted event of all queues:
void queue_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
var queue = (MessageQueue)sender;
var message = queue.EndReceive(e.AsyncResult);
var body = message.Body.ToString();
var xml = XDocument.Parse(body);
var queueName = queue.QueueName;
Type entityType = GetTypeFromQueueName(queueName);
entityType entity = DeserializeMessage<entityType>(xml);
var repository = new LogRepository();
repository.AddEntity<entityType>(entity);
}
private T DeserializeMessage<T>(XDocument message)
{
var serializer = new XmlSerializer(typeof(T));
var entity = (T)serializer.Deserialize(message.CreateReader());
return entity;
}
public Type GetTypeFromQueueName(string queueName)
{
switch (queueName)
{
case "some-message-queue-name":
return typeof (oneOfMyTypes);
}
}
But when I try to pass entityType to the generic methods I get "Type or namespace name expected".
I'm probably doing something really silly, but I can't figure out how this should work.
I've tried using the dynamic keyword and also .MakeGenericType but no luck.
I've also looked at:
- Dynamic Generic declaration of type T
- Function returning a generic type whose value is known only at runtime
- Determining a Generic Type at Runtime in Non-Generic Class
- How to pass variable of type "Type" to generic parameter
But I'm still not getting it ... help?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不幸的是,泛型并不意味着像这样动态运行。通用参数必须在设计时定义。自从我使用 NHibernate 以来已经有一段时间了,但是有没有一种方法可以使用如下语法插入实体:
EDIT:
或
Unfortunately, generics are not meant to function dynamically like this. Generic parameters must be defined at design time. It's been a while since I've used NHibernate, but isn't there a way to insert entities with a syntax like:
EDIT:
or
此链接应该可以帮助您
http://todotnet .com/post/2006/11/13/Instantiating-Generic-Types-at-runtime.aspx
您应该能够从我发布的链接通过反射调用该方法。
请参阅以下链接:
http://www.victorchen。 info/call-static-method-with-a-string-name/
因此,基本上,当您创建通用类型时,您将获取静态方法的 MethodInfo,然后在 MethodInfo 对象上调用 Invoke 方法。
(我实际上没有尝试过,但理论上我相信它应该有效)
This link should help you
http://todotnet.com/post/2006/11/13/Instantiating-Generic-Types-at-runtime.aspx
You should be able to go from the link i posted to call the methode through reflection.
See the following link:
http://www.victorchen.info/call-static-method-with-a-string-name/
So basically when you've created your generic Type, you then grab the MethodInfo of your static method and then call the Invoke method on the MethodInfo object.
(i haven't actually tried this but in theory i believe it should work)