Some common types that make working with events a bit easier to work with and understand.
That standard event
keyword in C# lacked (suitable) async support. It also produced memory leaks if handlers weren't removed, which was solved by using this library internally.
With the AsyncEventAggregator<T> : IAsyncEventAggregatorConsumer<T>
and non-async EventAggregator<T> : IEventAggregatorConsumer<T>
types, you can do the following:
public class MyEventData
{
public string Name { get; set; }
}
public interface IService
{
// Exposes .Subscribe() and .Unsubscribe()
IAsyncEventAggregatorConsumer<MyEventData> MyEvent { get; }
Task Hello(string name);
}
public class Service : IService
{
// Implements IAsyncEventAggregatorConsumer, but also
// has a .Publish() method, meant to be used internally.
private readonly AsyncEventAggregator<MyEventData> _myEvent = new AsyncEventAggregator<MyEventData>();
public IAsyncEventAggregatorConsumer<MyEventData> MyEvent => _myEvent;
public async Task Hello(string name)
{
await _myEvent.Publish(this, new MyEventData
{
Name = name
});
}
}
Then, when you consume it:
IService service = new Service();
IDisposable subscriptionScope = service.MyEvent.Subscribe((sender, data) =>
{
Console.WriteLine($"Hello {data.Name}!");
return Task.CompletedTask;
});
// Do something else, idk.
// All done with event handler, destroy.
subscriptionScope.Dispose();
With the ValueSource<T> : IValueSourceReadOnly<T>
type, you can do the following:
public interface IService
{
// Exposes .Subscribe() and .Unsubscribe()
IValueSourceReadOnly<string> Name { get; }
void ChangeName(string name);
}
public class Service : IService
{
private readonly ValueSource<string> _name = new ValueSource<string>();
public IValueSourceReadOnly<string> Name => _name;
public void ChangeName(string name)
{
_name.Change(name);
}
}
Then, when you consume it:
IService service = new Service();
IDisposable subscriptionScope = service.Name.ValueChanged.Subscribe((sender, name) =>
{
Console.WriteLine($"Name changed to {name}!");
Console.WriteLine($"Name: {service.Name.Value}");
});
service.ChangeName("Paul");
// All done with event handler, destroy.
subscriptionScope.Dispose();