Is there an example implementation of weak events using .NET's WeakEventManager?
I'm trying to implement it by following the "Notes to Inheritors" in the documentation, but it is vague. For example, I can't figure out how to call ProtectedAddListener
from my static AddListener
function in my custom manager.
I figured it out on my own following the guidelines in the "Notes for Inheritors" section of the WeakEventManager documentation. Here's a basic implementation of WeakEventManager
. The class sourcing the event is named PropertyValue
and the event is named Changed
.
public class PropertyValueChangedEventManager : WeakEventManager
{
public static PropertyValueChangedEventManager CurrentManager
{
get
{
var manager_type = typeof(PropertyValueChangedEventManager);
var manager = WeakEventManager.GetCurrentManager(manager_type) as PropertyValueChangedEventManager;
if (manager == null)
{
manager = new PropertyValueChangedEventManager();
WeakEventManager.SetCurrentManager(manager_type, manager);
}
return manager;
}
}
public static void AddListener(PropertyValue source, IWeakEventListener listener)
{
CurrentManager.ProtectedAddListener(source, listener);
}
public static void RemoveListener(PropertyValue source, IWeakEventListener listener)
{
CurrentManager.ProtectedRemoveListener(source, listener);
}
protected override void StartListening(object source)
{
((PropertyValue)source).Changed += DeliverEvent;
}
protected override void StopListening(object source)
{
((PropertyValue)source).Changed -= DeliverEvent;
}
}
Sharp Observation is an open source project that has an easy to use implementation. You might want to take a look at their code or just use it as-is.
Usage
The MakeWeak() method returns a new delegate which invokes the same
target as the original delegate, but holds a weak reference to the
target so that the listener is not kept alive by the delegate:
var handler= new PropertyChangingEventHandler(listener.HandleChange);
observable.PropertyChanging += handler.MakeWeak<PropertyChangingEventHandler>();
Limitations
The current implementation has the following restrictions on delegates:
- Return values are not supported.
- Arguments of Out and Ref are not supported.