Jon Skeet Singleton and EventAggregator
Asked Answered
G

1

8

For the sake of simple inter-module communication there were classic .NET events, but there are too many right now and there are chains of events calling each other through modules.

Like Event_A triggers Event_B which fires Event_C.

The EventAggregator is very handy for decoupled communication in one module, so I tried the little "Jon Skeet Singleton IV" with an EventAggregator in it to break those event chains. Jon Skeet on C# singletons can be found here

He tells that it is threadsafe, but his example does nothing more than exposing a Singleton resource.

Here is my code

public static class GlobalEventAggregator
{
    private static readonly IEventAggregator EventAggregator = new EventAggregator();

    // tell C# compiler not to mark type as beforefieldinit
    static GlobalEventAggregator()
    {
    }

    public static void Subscribe(object instance)
    {
        EventAggregator.Subscribe(instance);
    }

    public static void Unsubscribe(object instance)
    {
        EventAggregator.Unsubscribe(instance);
    }

    public static void Publish(object message)
    {
        EventAggregator.Publish(message);
    }
}

Now I could use this GlobalEventAggregator in every module to Publish events and every other module which is interested in those events can happily handle them. No more chaining.

But will I get multithreading issues with that? The other modules have different threads and I want to Publish events in them. The Dispatching should not be a problem. Should I use lock in the public methods?

I cannot tell whether those methods are threadsafe and cannot find documentation on that.

Godfearing answered 13/2, 2014 at 18:34 Comment(5)
You may want to read this. CSharpMessengerUribe
I'm not a fan of string-based messenger systems, as there is no convenient way to find all publishers or all subscribers of the event. With strongly typed messages, you can easily find usages on the type and get all the information you are looking for. See Galasoft Messenger: blog.galasoft.ch/posts/2009/09/mvvm-light-toolkit-messenger-v2Monamonachal
@Uribe Thank you for your suggestion. Thought that more people had that kind of problem before. Perhaps that Messanger is better than rolling my own.Godfearing
@all The EventAggregator is already some kind of Messanger. All I want to do is making it accessible for more than one module.Godfearing
A bit late, but TinyMessenger is the easiest local event aggregator I have used so far.Opsonize
T
3

EventAggregator already locks so your GlobalEventAggregator won't need to. http://caliburnmicro.codeplex.com/SourceControl/latest#src/Caliburn.Micro/EventAggregator.cs

Kind of unrelated, but the recommended way to access the singleton is through DI.

Teryn answered 10/3, 2014 at 4:11 Comment(3)
This means I shall have a global DI Container for all modules?Godfearing
The caliburn micro proj has samples of the bootstrapper setup: caliburnmicro.codeplex.com/SourceControl/latest#samples/… The idea is you register the eventaggregator in the bootstrapper and the objects get instances of that eventaggregator automatically via constructor or property injection.Teryn
This is how I do it in one module. The problem here is that there are many modules that I want to give a way of communication.Godfearing

© 2022 - 2024 — McMap. All rights reserved.