0

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.

Community
  • 1
  • 1
Leaky
  • 3,088
  • 2
  • 26
  • 35
  • are you looking to have a type associated with the event? I guess you could also send "" as well. _eventAggregator.PublishOnUIThread(""); – d.moncada Apr 06 '17 at 14:45
  • Yes, I'd like the events to be identifiable in some way, and to implement IHandle and Handle() in a way that doesn't necessitate additional "if" checks in the receiving classes (e.g. they are not receiving events that are useless for them). If I could use the sender of the event, that would be perfect in this small project. Maybe I should try to decorate the EventAggregator class with additional functionality? – Leaky Apr 06 '17 at 14:52

1 Answers1

2

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;
        }
    }
}
Joel Lucsy
  • 8,520
  • 1
  • 29
  • 35
  • Thanks! Do you think I could avoid somehow that switch? (And only receive e.g. ProjectSignals.Connected.) I'll upvote your answer definitely, but I ran out of votes for today. :) – Leaky Apr 06 '17 at 14:56
  • Not directly. The publish is based on the type of the object. You could create a single enum per thing you want to catch. One for connected, one for Disconnected, and so on. – Joel Lucsy Apr 06 '17 at 15:05
  • Yes, that would be definitely viable, but similarly to the empty classes, the empty enums look a bit bizarre; I was hoping for something that "feels right". Not sure though if this is the right attitude in this case. :) – Leaky Apr 06 '17 at 15:14
  • I guess the point of using enums is that its lighter weight, slightly less memory pressure. – Joel Lucsy Apr 06 '17 at 15:17
  • Yes, you're right. If it's okay, I'll leave it open for now; maybe I can find or come up with some decoration of the EventAggregator class that can solve it neatly. But I'll definitely come back to upvote tomorrow. – Leaky Apr 06 '17 at 15:21