There are certain solutions for this, here is one: create separate implementations for IEventPublisher<T> and IEventSubscriber<T> and let them delegate the EventMediator<T> command. For example, with these implementations:
public class EventPublisher<TEvent> : IEventPublisher<TEvent> { private readonly EventMediator<TEvent> mediator; public EventPublisher(EventMediator<TEvent> mediator) { this.mediator = mediator; } public void Publish(TEvent Event) { this.mediator.Publish(Event); } } public class EventSubscriber<TEvent> : IEventSubscriber<TEvent> { private readonly EventMediator<TEvent> mediator; public EventSubscriber(EventMediator<TEvent> mediator) { this.mediator = mediator; } public void Subscribe(Action<TEvent> CallBack) { this.mediator.Subscribe(Callback); } }
Now you do the registration as follows:
container.RegisterSingleOpenGeneric(typeof(EventMediator<>), typeof(EventMediator<>)); container.RegisterSingleOpenGeneric(typeof(IEventPublisher<>), typeof(EventPublisher<>)); container.RegisterSingleOpenGeneric(typeof(IEventSubscriber<>), typeof(EventSubscriber<>));
Now both EventPublisher<DummyEvent> and EventSubscriber<DummyEvent> will point to the same instance of EventMediator<DummyEvent> .
Another way to achieve this without an additional type is to use the ResolveUnregisteredType event (which itself uses the RegisterOpenGeneric extension method under covers). Your configuration will look like this:
container.RegisterSingleOpenGeneric(typeof(EventMediator<>), typeof(EventMediator<>)); container.ResolveUnregisteredType += (s, e) => { if (e.UnregisteredServiceType.IsGenericType) { var def = e.UnregisteredServiceType.GetGenericTypeDefinition(); if (def == typeof(IEventPublisher<>) || def == typeof(IEventSubscriber<>)) { var mediatorType = typeof(EventMediator<>) .MakeGenericType(e.UnregisteredServiceType.GetGenericArguments()[0]); var producer = container.GetRegistration(mediatorType, true); e.Register(producer.Registration); } } };
You can even extract this code into a more general extension method. Thus, your registration will look like this:
container.RegisterSingleOpenGeneric(typeof(EventMediator<>), typeof(EventMediator<>)); container.ForwardOpenGenericTo(typeof(IEventPublisher<>), typeof(EventMediator<>)); container.ForwardOpenGenericTo(typeof(IEventSubscriber<>), typeof(EventMediator<>));
The extension method will look like this:
public static void ForwardOpenGenericTo(this Container container, Type openGenericServiceType, Type openGenericServiceTypeToForwardTo) { container.ResolveUnregisteredType += (s, e) => { var type = e.UnregisteredServiceType; if (type.IsGenericType) { if (type.GetGenericTypeDefinition() == openGenericServiceType) { var forwardToType = openGenericServiceTypeToForwardTo.MakeGenericType( type.GetGenericArguments()); var producer = container.GetRegistration(forwardToType, true); e.Register(producer.Registration); } } }; }