Dynamic Topic

Jan 9, 2012 at 8:00 PM

When creating a dynamic topic, what Type should be used for the OnMessageReceived?  I didn't see an example of handling the message but maybe I missed it.

Topic.New("MyTopic")
.Description("My Topic Description")
.AddParameter("Param1", "Param1 Description")
.AddParameter("Param2", "Param2 Description")
.Register();

subscriber.OnMessageReceived<???>("Tcp",
                msg =>
                {
                    HandleMessage(msg);

                },
                error =>
                {
                    error.Continue = true;
                    Console.WriteLine(error.Error.ToString());
                },
                TimeSpan.FromMilliseconds(100),
                1);

 

Coordinator
Jan 9, 2012 at 8:16 PM

You can create any Type you want, you can do either of the following.

public class MyTopic{     

public string Param1 {get;set;}     

public string Param2 {get;set;}

}
or

public interface IMyTopic {

  string Param1 {get;set;}

string Param2 {get;set;}

}

 

subscriber.OnMessageReceived<IMyTopic> or subscriber.OnMessageReceived<MyTopic> is fine

The Generic Type you are passing to it can be either a class or an interface. The Name of the class or interface does not have to match your topic name. The most important thing is having the correct properties name and type that you are excepting to get.


Thanks again, I will put up a document on how to receive messages for dynamic topics soon. I would highlight the different between using interfaces and classes

Jan 9, 2012 at 8:29 PM

Fair enough...I was trying to make the handler totally dynamic based on the Topic.

subscriber.OnMessageReceived<object>("Tcp",
msg =>
{
HandleMessage(msg);

},
error =>
{
error.Continue = true;
Console.WriteLine(error.Error.ToString());
},
TimeSpan.FromMilliseconds(100),
1);

 

public class MyClass
{
	public void HandleMessage(object message)
	{
		dynamic myMessage = message;
		//Determine at runtime
            	string firstName = myMessage.FirstName.ToString();
	}
}
Coordinator
Jan 9, 2012 at 8:43 PM
Edited Jan 9, 2012 at 8:46 PM

You can still do that if you generate the type on the fly doing the following:

A similar code like below is used for the websocket and http streaming logic for the javascript api too

The code below assume you are using 2.0.0 if you are using a version below 2.0.0 then just change ReflectionHelper to InterfaceMapper. The class can be found by referencing PServiceBus.Core

//This will generate a type with the name MyTopicType and add two properties which are both string types

var messageType = ReflectionHelper.GenerateClassType("MyTopicType", new Dictionary<string, object>{ {"Param1", ""}, {"Param2", ""} });

MethodInfo messageReceivedMethod = typeof(Subscriber).GetMethod("OnMessageReceived");
var genericMethod = messageReceivedMethod.MakeGenericMethod(messageType);
               //Hold reference for handler in other to use TransportsHandler.Shutdown(handler) to kill it later
                var handler = genericMethod.Invoke(subscriber, new object[] { 
                webSocketSubscriberInfo.TransportName, new Action<object>(msg => HandleMessage(msg)),
                new Action<HandleErrorArgs>(errorHandler => {
                    errorHandler.Continue = true;
                }),
                TimeSpan.FromMilliseconds(100)});
Coordinator
Jan 9, 2012 at 8:51 PM

I would add another method soon that would allow using of dynamic topic handler easier. so you would not have to write the above all the time.