4

I am looking into how an event aggregator can be implemented directly in the DI container and struggling how to do that with DryIoC.

I have the following example services and contracts for the event aggregation:

public class EventHub<T> : IPublisher<T>, ISubscriber<T>
{
    private List<Action<T>> listeners = new List<Action<T>>();

    public void Publish(T data)
    {
        foreach (var listener in listeners)
        {
            listener(data);
        }
    }

    public void Register(Action<T> listener)
    {
        listeners.Add(listener);
    }

    public void Unregister(Action<T> listener)
    {
        listeners.Remove(listener);
    }
}

public interface IPublisher<T>
{
    void Publish(T data);
}

public interface ISubscriber<T>
{
    void Register(Action<T> listener);

    void Unregister(Action<T> listener);
}

Now, if someone resolves a publisher or subscriber for a specific type, I would like the DI container to always return the same event hub.

I tried multiple registrations of the EventHub class, but all of them have their specific problems:

Separate registrations

Container.Register(typeof(IPublisher<>), typeof(EventHub<>), Reuse.Singleton);
Container.Register(typeof(ISubscriber<>), typeof(EventHub<>), Reuse.Singleton);

The problem here is that DryIoC does not couple the registrations, i.e. for each type there will be two implementations.

Registration mapping

Container.Register(typeof(EventHub<>), typeof(EventHub<>), Reuse.Singleton);
Container.RegisterMapping(typeof(IPublisher<>), typeof(EventHub<>));
Container.RegisterMapping(typeof(ISubscriber<>), typeof(EventHub<>));

DryIoC (v2.12.10) does not support that and throws an error message when trying to register the first open generic mapping.

RegisterMany

Container.RegisterMany(new [] {typeof(IPublisher<>), typeof(ISubscriber<>)}, typeof(EventHub<>), Reuse.Singleton);

This actually works, but still resolves different instances for publishers and subscribers.

Is there a way to make this behavior work?

Georg
  • 5,626
  • 1
  • 23
  • 44
  • Btw, any reason you are not using V3? The fix will go to V3, and probably not to V2. – dadhi Aug 08 '18 at 09:46
  • @dadhi Because there is a Prism integration for v2 that does not work with v3 – Georg Aug 08 '18 at 11:07
  • OK.. meanwhile you may consider other well known EventAggregator implementations working with DI, e.g. https://github.com/jbogard/MediatR. Or implement your own avoiding generics in Hub class, e.g. https://github.com/dadhi/DryIoc/blob/master/Net45/DryIoc.IssuesTests/Issue110_SupportContravarianceInResolveMany.cs Or https://github.com/dadhi/DryIoc/blob/master/Net45/DryIoc.IssuesTests/Issue164_EventAggregatorImpl.cs – dadhi Aug 08 '18 at 12:38

1 Answers1

0

It is likely a bug. I have added new issue to DryIoc GitHub repo. Stay tuned for update.

dadhi
  • 4,807
  • 19
  • 25