I am building an app where we are pulling messages off of MSMQ. The idea is to then take that message find a handler for it and process the message.
The method that is doing the retrieval and kicking off the processing looks like this
private void DoWork(object state)
{
var mq = MessageQueue.Exists(QueueName)
? new MessageQueue(QueueName)
: MessageQueue.Create(QueueName);
var message = mq.Receive();
message.Formatter = new XmlMessageFormatter
{TargetTypes = new[]
{typeof(Envelope<SerializableDictionary<string, dynamic>>)}};
var handler = _handlerMap[message.Label];
handler.Handle(message.Body);
ThreadPool.QueueUserWorkItem(DoWork);
The Handler being returned is an inheritor of an abstract base class and here are those to classes
public abstract class MessageHandler<T>
{
protected abstract JobStatus ProcessMessage(Envelope<T> envelope);
private IContext Context { get; set; }
protected MessageHandler()
{
Context = new ContextBuilder().CreateContext();
}
public void Handle(Envelope<T> envelope)
{
var job = Context.Jobs
.First(repoJob => repoJob.Name.Equals(envelope.MessageId));
AddLogToJob(job, JobStatus.InProgress);
var status = ProcessMessage(envelope);
AddLogToJob(job, status);
}
private void AddLogToJob(Job job, JobStatus status)
{
job.JobLogs.Add(new JobLog { JobId = job.Id, StatusId = status.Id });
Context.SaveChanges();
}
}
}
Here is the specific handler
public class MappingHandler<T> : MessageHandler<IDictionary<string, dynamic>>
{
public DictionaryMapper<T> Mapper { get; set; }
public Func<T> Constructor { get; set; }
protected override JobStatus ProcessMessage(
Envelope<IDictionary<string, dynamic>> envelope)
{
Mapper.Map(envelope.Payload, Constructor());
return JobStatus.Completed;
}
}
When I try to actually run the process when it reaches the handler.Handle(message.Body) line it throws a RuntimeBinderException. I haven't worked with dynamics much so it could likely be something in there, but everything I see in the debugger makes me think it should be working.