You can use the following pattern. First create class which will run arbitrary function you pass on construction and another on dispose:
public class EventSubscription : IDisposable {
private readonly Action _unsubscribe;
private EventSubscription(Action subscribe, Action unsubscribe) {
_unsubscribe = unsubscribe;
subscribe();
}
public static IDisposable Create(Action subscribe, Action unsubscribe) {
return new EventSubscription(subscribe, unsubscribe);
}
public void Dispose() {
_unsubscribe();
}
}
Then create field in your class where you subscribe to events:
private static readonly List<IDisposable> _subscriptions = new List<IDisposable>();
And subscribe like this:
_subscriptions.Add(EventSubscription.Create(
() => Event1 += OnEvent1,
() => Event1 -= OnEvent1));
_subscriptions.Add(EventSubscription.Create(
() => Event2 += OnEvent2,
() => Event2 -= OnEvent2));
When you need to unsubsribe, just do:
_subscriptions.ForEach(c => c.Dispose());
Advantages include unsubscribing from all at once, and much less chance to forget to unsubscribe, because you always pass +=
and -=
handler in pair, in the same call.
Variation of this is this general purpose class:
public class Disposable : IDisposable {
private readonly Action _action;
private Disposable(Action action) {
_action = action;
}
public static IDisposable FromAction(Action action) {
return new Disposable(action);
}
public void Dispose() {
_action();
}
}
You can find it already in many places (like .NET reactive extensions), but if not - you can implement yourself. Then above code becomes:
Event1 += OnEvent1;
_subscriptions.Add(Disposable.FromAction(() => Event1 -= OnEvent1));
Using IDisposable is not necessary of course, you can just have list of Actions.