调解员模式问题

时间:2014-01-20 12:17:28

标签: c# design-patterns mediator

我正在使用bellow类在C#应用程序中实现中介模式。我注意到如果我有多个订阅者(对象)订阅了同一个事件,那么只有其中一个接收它。这是正常行为吗?我怎样才能实现所有人都接受它?

举起活动的主要对象

Mediator.NotifyColleagues("SetMyProject", MyProject);

通过下面的线

订阅多个对象(类)
Mediator.Register("SetMyProject", SetMyProject);

调解员班

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);
    }
}

2 个答案:

答案 0 :(得分:1)

嗯,你不应该害怕括号。

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

问题在于item.Method.ToString(),请尝试比较操作对象,如下所示:

foreach (var item in pl_dict[token])
{
    if (item == callback)
    {
        found = true;
        break; // no need to continue
    }
}
顺便说一句,为什么你不使用pl_dict[token].Contains(callback),你应该工作:

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

答案 1 :(得分:1)

在这一行item.Method.ToString() == callback.Method.ToString(),你实际上是匹配的方法签名,即使它们来自不同的类,也可能是相同的。

你可能想尝试这样的事情,

if (item.Method.ReflectedType.Name + "." + item.Method.Name == callback.Method.ReflectedType.Name+"."+callback.Method.Name)
{ found = true; }