Leaky
Leaky

Reputation: 3646

How to use Caliburn Micro's EventAggregator to send empty events (no payload)?

I found articles about and solutions to this question pertaining to Prism, but I didn't find anything pertaining to Caliburn Micro. I checked all questions here tagged with Caliburn.Micro and EventAggregator, but didn't find anything Caliburn specific about this seemingly basic issue.

Scenario: I want to publish events to the EventAggregator that don't have any information, other than signaling that something happened.

Problem: First, in Caliburn Micro, the EventAggregator's Publish() method requires an instance of a type to be sent. Second, subscribing and handling events require the implementation of the IHandle<T> interface, where T is the type of instances that we want to receive. It seems that this is fully designed around publishing and handling actual data.

Goal: To be able to publish simple events without having to create and instantiate multiple empty/dummy classes, and without having to Handle() unnecessary events that I need to filter further with conditionals.


My solution so far

This is what I want to improve/replace. (Obviously, this solution is problematic because it creates tighter coupling around the concrete classes, but in my use case this is not a big issue, since it's a small project with singular publishing components for a given event, and the EventAggregator serves other practical goals.)

I made a generic Signal<T> class that implements the singleton pattern, providing a static instance of itself through the Instance property:

public class Signal<T>
{
    public static readonly Signal<T> Instance = new Signal<T>();

    private Signal() { }
}

So I can publish events in the following way (SignalSourceClass is an example):

_eventAggregator.PublishOnUIThread(Signal<SignalSourceClass>.Instance);

And handle events by declaring the implementation of IHandle<T> in the following way:

IHandle<Signal<SignalSourceClass>>

This way I can send and receive "empty" events by creating only this single Signal class. (Of course this is a limited solution, since components can only send one event this way.)

I suspect that this solution is primitive (well, let's just call it a fact), and that there is something better that I'm overlooking.

Upvotes: 1

Views: 635

Answers (1)

Joel Lucsy
Joel Lucsy

Reputation: 8706

Just create a enum with all possible signals you want:

public enum ProjectSignals
{
    Connected,
    Disconnected,
    Openned
}

then just

_eventAggregator.PublishOnUIThread( ProjectSignals.Connected );

and

class SomeClass : IHandle<ProjectSignals>
{
   public void Handle( ProjectSignals signal )
   {
        switch (signal)
        {
            case Connected:
                break;
        }
    }
}

Upvotes: 2

Related Questions