【问题标题】:Mediator pattern issue中介者模式问题
【发布时间】:2014-01-20 12:17:28
【问题描述】:

我正在使用波纹管类在 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);
    }
}

【问题讨论】:

    标签: c# design-patterns mediator


    【解决方案1】:

    mhhh,你不应该害怕括号。

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

    【讨论】:

    • 我不知道为什么这会影响其他收件人接收邮件
    • 因为Action&lt;object&gt;.Method返回MethodInfo,而MethodInfo没有重新定义ToString,所以你调用的是Object.ToString。通过阅读文档here 我可以看出 item.Method.ToString 返回"System.Reflection.MethodInfo"
    • 实际上,这个成功了......将为当前项目保留这个解决方案,但将转移到 prism eventagregator
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-14
      • 2021-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多