6

弱いイベント パターンを使用してイベントにサブスクライブすることを検討しています。.NET 4.5 フレームワークでは、洗練された外観のWeakEventManagerクラスがあります。イベントへの弱いサブスクライブは、次のように簡単です。

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

しかし、私は「stringly-typed」コードの大ファンではありません。サブスクライブするイベントの文字列名を使用する方法を見つけようとしています。イベントの名前を取得する唯一の方法は、イベントを定義するクラスでラムダ式を使用することです。私のシナリオでは、イベントを定義するクラスを所有しているので、好きなように変更できます。私は自分のイベントを購読および購読解除するためのクリーンな方法を見つけようとしていますが、これが私が最も嫌いなものです.

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

カスタム イベント アクセサーを使用することで、LoggingOn_Subscribe(EventHandler) のような不格好な (私の意見では) メソッドや、各イベントの名前プロパティの追加を回避できました。残念ながら、イベントにサブスクライブしている人々が従来の方法でサブスクライブしているため、それほど直感的ではありませんが、サブスクライブが弱いことを示す名前の "_Weak" 部分以外はわかりません。

私の質問に関しては..

1) 弱いイベントやカスタム イベント アクセサーを使用したことがありません。上記のコードは機能しているように見えますが、技術的に問題がないことを確認したいと思います。ここで自分の足を撃つために何かしていることはありますか?

2) デザインの観点から、これはひどい考えですか? 考慮すべき重要な設計上の問題はありますか? より良い代替手段はありますか?文字列型のイベント名を使用してサブスクライバーからサブスクライブする必要がありますか?

考え?

4

2 に答える 2

3

.NET 4.6 では、nameof() 式を使用できるようになりました。

WeakEventManager<IMyGrid, MyEventArgs>.AddHandler(myGrid, nameof(IMyGrid.MouseDown), OnMouseDown);
于 2016-12-05T00:49:18.417 に答える
-1

できることは、組み込みの System.ComponentModel.EventHandlerList を使用することです。このクラスは、オブジェクトのすべてのイベント ハンドラー デリゲートのコンテナーです。主な利点は、実際に誰かがイベントをサブスクライブしない限り、各イベントのオブジェクトにストレージが割り当てられないことです。

2 つ目の利点は、それを使用するには、イベントのキーを提供する必要があることです。

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);
于 2012-10-26T18:10:58.817 に答える