【问题标题】:WeakEventManager with event name lambda expression and custom event accessors带有事件名称 lambda 表达式和自定义事件访问器的 WeakEventManager
【发布时间】:2012-10-16 19:57:16
【问题描述】:

我一直在寻找使用弱事件模式订阅事件。使用 .NET 4.5 框架,我们有一个漂亮的 WeakEventManager 类。弱订阅一个事件就这么简单

WeakEventManager<EventSource, SomeEventEventArgs>.AddHandler(source, "SomeEvent", source_SomeEvent);

不过,我不是“字符串类型”代码的忠实拥护者。我一直在尝试找到一种方法来使用要订阅的事件的字符串名称。我发现获取事件名称的only way 是在定义事件的类中使用 lambda 表达式。在我的场景中,我拥有定义事件的类,因此我可以随意更改它。我一直在尝试找到一种干净的方式来订阅和取消订阅我的活动,这是我最不喜欢的。

public event EventHandler<EventArgs> LoggingOn;
public event EventHandler<EventArgs> LoggingOn_Weak
{
    add
    {
        var eventName = this.GetEventName(() => this.LoggingOn);
        WeakEventManager<CurrentUser, EventArgs>.AddHandler(this, eventName, value);
    }

    remove
    {
        var eventName = this.GetEventName(() => this.LoggingOn);
        WeakEventManager<CurrentUser, EventArgs>.RemoveHandler(this, eventName, value);
    }
}

// In a base class view model in my scenario
private string GetEventName<T>(System.Linq.Expressions.Expression<Func<T>> expression)
{
    return (expression.Body as System.Linq.Expressions.MemberExpression).Member.Name;
}

protected void OnLoggingOn(object sender, EventArgs e)
{
    var handler = this.LoggingOn;
    if (handler != null)
    {
        handler(sender, e);
    }
}

使用custom event accessors 我能够避免笨拙的(在我看来)方法,如 LoggingOn_Subscribe(EventHandler) 或为每个事件添加名称属性。不幸的是,订阅该事件的人以经典方式订阅该事件并不那么直观,但除了名称中的“_Weak”部分之外一无所知,表明它正在被弱订阅。

至于我的问题..

1) 我以前从未使用过弱事件或自定义事件访问器。上面的代码似乎可以工作,但是,我只想确保它在技术上没有任何问题。有什么我正在做的事情是为了在脚上开​​枪吗?

2) 从设计的角度来看,这是一个糟糕的想法吗?我应该考虑任何主要的设计问题吗?有更好的选择吗?我是否应该接受它并使用字符串类型的事件名称从我的订阅者那里订阅?

想法?

【问题讨论】:

    标签: c# .net weak-events


    【解决方案1】:

    在 .NET 4.6 中,您现在可以使用 nameof() 表达式:

    WeakEventManager<IMyGrid, MyEventArgs>.AddHandler(myGrid, nameof(IMyGrid.MouseDown), OnMouseDown);
    

    【讨论】:

      【解决方案2】:

      您可以做的是使用内置的 System.ComponentModel.EventHandlerList。此类是对象的所有事件处理程序委托的容器。主要好处是不会为每个事件在您的对象上分配存储空间,除非确实有人订阅了某个事件。

      第二个好处是,为了使用它,您必须为您的活动提供密钥。

      class MyObject
      {
          protected EventHandlerList Events = new EventHandlerList();
      
          public static Event1Key = new object();
          public event Event1
          {
              add { Events.AddHandler(Event1Key, value); }
              remove { Events.RemoveHandler(Event1Key, value); }
          }
      }
      

      现在您可以创建一个 WeakEventManager 的变体,它接受键而不是字符串名称。所以消费者可以说

      WeakEventManager<EventSource, SomeEventEventArgs>.AddHandler(source, EventSource.Event1Key, source_SomeEvent);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-30
        • 1970-01-01
        • 1970-01-01
        • 2017-06-30
        • 2015-09-20
        • 2013-11-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多