4

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:

But I'm still not getting it ... help?

Community
  • 1
  • 1
autonomatt
  • 4,393
  • 4
  • 27
  • 36
  • So the gist of my question is: I have a method that takes a generic parameter. I want to decide at runtime which type to pass to this method. How do I do that? – autonomatt Sep 02 '10 at 14:30
  • You should explain what you meant by "no luck". What went wrong with approaches in those questions? `MakeGenericMethod` is what you have to use. – nawfal Jan 18 '14 at 05:22
  • possible duplicate of [How to use reflection to call generic Method?](http://stackoverflow.com/questions/232535/how-to-use-reflection-to-call-generic-method) – nawfal Jan 18 '14 at 05:22

2 Answers2

0

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)

F.B. ten Kate
  • 2,032
  • 2
  • 21
  • 31
  • I'm not sure this answers my questions. All I want to do is this: Given myMethod(), at runtime, if x = 1 then call myMethod() if x = 2 then call myMethod()... – autonomatt Sep 02 '10 at 14:36
  • Yes i know, basically the following link did all the legwork i didn't i simply gave a few links and hoped you'd figure out the rest :) http://stackoverflow.com/questions/232535/how-to-use-reflection-to-call-generic-method – F.B. ten Kate Sep 02 '10 at 17:45
0

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:

repository.AddEntity(entity, typeof(myEntityType));

EDIT:

or

 Session.SaveOrUpdate(object);
Steve Danner
  • 21,818
  • 7
  • 41
  • 51
  • I believe atm it should something like Session.SaveOrUpdate(object) i believe NHibernate does not care what type your send in as it will use reflection to figure out what it is saving. – F.B. ten Kate Sep 02 '10 at 13:40
  • Good call, I edited to show both since he's using the repository pattern above, I think both snippets might be useful. – Steve Danner Sep 02 '10 at 13:51
  • Thanks. It's not so much the call to NHibernate, but rather the DeserializeMessage(message) call that I'm trying to get working... – autonomatt Sep 02 '10 at 13:53
  • So if generic paramters must be defined at design time, then should I use a dynamic type? ... or should I just use a type of object and then cast to one of my types? – autonomatt Sep 02 '10 at 14:38
  • I personally would just have it return type object and cast it explicitly like you already do in the DeserializeMessage method. Maybe you've got a base class or interface you could return from that method instead? – Steve Danner Sep 02 '10 at 14:51
  • Unfortunately, there is no common interface. These classes are just property bags. Shame, I thought generics was supposed to alleviate boxing. – autonomatt Sep 02 '10 at 15:00