Question

I am implementing mediator pattern in C# application using the bellow class. I've noticed that if I have multiple reipents (objects) subscribed to the same event, only one of them receives it. Is this a normal behaviour? How can I achieve that all of them receives it?

Main object which raise event

Mediator.NotifyColleagues("SetMyProject", MyProject);

Multiple objects (classes) are subscribed via bellow line

Mediator.Register("SetMyProject", SetMyProject);

Mediator class

static public class Mediator
{
    static IDictionary<string, List<Action<object>>> pl_dict = new Dictionary<string, List<Action<object>>>();

    static public void Register(string token, Action<object> callback)
    {
        if (!pl_dict.ContainsKey(token))
        {
            var list = new List<Action<object>>();
            list.Add(callback);
            pl_dict.Add(token, list);
        }
        else
        {
            bool found = false;
            foreach (var item in pl_dict[token])
                if (item.Method.ToString() == callback.Method.ToString())
                    found = true;
            if (!found)
                pl_dict[token].Add(callback);
        }
    }

    static public void Unregister(string token, Action<object> callback)
    {
        if (pl_dict.ContainsKey(token))
            pl_dict[token].Remove(callback);
    }

    static public void NotifyColleagues(string token, object args)
    {
        if (pl_dict.ContainsKey(token))
            foreach (var callback in pl_dict[token])
                callback(args);
    }
}
Was it helpful?

Solution

mhhh, you should not be afraid of brackets.

foreach (var item in pl_dict[token])
    if (item.Method.ToString() == callback.Method.ToString())
        found = true;

The problem is with item.Method.ToString(), try just comparing the action objects, like this:

foreach (var item in pl_dict[token])
{
    if (item == callback)
    {
        found = true;
        break; // no need to continue
    }
}

BTW, why didn't you use pl_dict[token].Contains(callback), y should work:

if (!pl_dict[token].Contains(callback))
{
    pl_dict[token].Add(callback);
}

OTHER TIPS

At this line item.Method.ToString() == callback.Method.ToString() you are practically matching method signature which might be the same even if they are from different classes.

You might want to try something like this,

if (item.Method.ReflectedType.Name + "." + item.Method.Name == callback.Method.ReflectedType.Name+"."+callback.Method.Name)
{ found = true; }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top