Message Bus - enum token?

Sep 26, 2011 at 6:51 AM
Edited Sep 26, 2011 at 7:14 AM

I'm just getting started with Simple MVVM Toolkit. Looks very promising so far.

I'm curious about one thing, though: why restrict the message bus token to a string? It seems like an enum would be a better fit.

Compare:

Enum:

 

public enum MessageToken
{
    Next,
    Previous,
    Up,
    Down
}

 

Class of string constants:

 

public class MessageToken
{
    public const string Next = "Next";
    public const string Previous = "Previous";
    public const string Up = "Up";
    public const string Down = "Down";
}

 

Besides having to type "public const string" for each token, every string field needs to be "double-named" (i.e., you need to enter a name for both the field's name and value). This makes refactoring more work and more error prone, since you can't just do a simple refactor/rename operation, you have to also change the string's value. (Admittedly, the consequences of forgetting to rename a string are not likely to be catastrophic, but it could cause confusion during debugging if your message token is not what you expect.) With an enum, you just have to type the name of each token, and refactoring is a breeze.

There may be occasions where an enum won't work, so I wouldn't remove the possibility of using a string altogether, but it would be nice if enum where a possibility. Also, uniqueness of each value is guaranteed, so you won't end up sending a message that gets picked up by an unintended receiver.

If you were to implement this feature, you could make a generic version of the MessageBus class that allows specification of a particular enum for tokens.

Meanwhile, I'm thinking of doing something like this as a workaround:

public void Save()
{
    SendMessage(MessageToken.Navigation.ToString(),
        new NotificationEventArgs(PageNames.Home));
}
Coordinator
Sep 26, 2011 at 12:56 PM

Great point about the drawbacks of using a string as the message token type.  Other toolkits set it as object, which offers better flexibility (you can use whatever you want) but is more prone to error (you need to make sure sender and receiver use the same message token type).  Ultimately, for the sake of simplicity, I opted for string as the token type, with the understanding that you can always call ToString on whatever type you decide to use, for example, Enum.ToString or Guid.ToString.  What would be interesting is a generic overload of the send and receive methods that accept a type argument for the token type.  This would allow you to specify an enum for the token type.  I'll put that on the wish list for version 2.x.

What I was thinking for the next version is to both address some of the bugs that people have found -- although there don't seem to be too many ;-) -- and to include some requested features, such as this one.

Cheers,

Tony

Sep 26, 2011 at 6:10 PM

Thanks for the speedy reply. I guess there are a couple of use cases for messenger tokens: (1) You want to listen for all messages of type int/string/Foo/Whatever, and you don't care what the value is. (2) You want to listen for a message of type int/string/Foo/Whatever and you *do* care what the value is. (Presumably, enums would fall into the second category.) I'm not sure if (1) is a common use case, but I figure it would be something worth thinking about as you add overloads.

The other issue is whether to add a generic version of the MessageBus class (as I proposed), make the send/register methods generic (as you proposed), or both. If you allow the entire class to be generic, it simplifies the syntax of send/receive, and also adds a degree of enforcement (if you try to send a message with a "string" token when the message bus is expecting "int" tokens, it won't compile). This *would* require some sort of custom initialization on the part of the toolkit user. Adding overloads with the methods would clearly allow for more flexibility (but less control). Obviously, doing both would offer the best of both worlds, but at the cost of complexity.