DryIOC Event Aggregator

為{幸葍}努か 提交于 2019-12-06 07:59:45

问题


I'm trying to Implement an event aggregator using DryIOC. I have an Event dispatcher as follows:

public class DryIocEventDispatcher : IEventDispatcher
{
    private readonly IContainer _container;

    public DryIocEventDispatcher(IContainer container)
    {
        _container = container;
    }

    public void Dispatch<TEvent>(TEvent eventToDispatch) where TEvent : EventArgs
    {
        foreach (var handler in _container.ResolveMany<IHandles<TEvent>>())
        {
            handler.Handle(eventToDispatch);
        }
    }
}

I have a number of classes that can handle events. Indicated by the following Interface:

public interface IHandles<T> where T : System.EventArgs
{
    void Handle(T args);
}

The gist of it is, that when I call the event dispatcher dispatch method, and pass in a type that inherits from EventArgs. It grabs from the IOC Container, all the types that Implement IHandles<> and call the handle method on them.

An event type may be handled by multiple Services. And a service can handle multiple event types. e.g:

public class ScoringService : IHandles<ZoneDestroyedEventArgs>, IHandles<ZoneCreatedEventArgs>
{
    public void Handle(ZoneDestroyedEventArgs args)
    {
        Console.WriteLine("Scoring Service Handled ZoneDestroyed Event");
    }

    public void Handle(ZoneCreatedEventArgs args)
    {
        Console.WriteLine("Scoring Service Handled ZoneCreated Event");
    }
}

public class RenderingService : IHandles<ZoneDestroyedEventArgs>, IHandles<ZoneCreatedEventArgs>
{
    public void Handle(ZoneDestroyedEventArgs args)
    {
        Console.WriteLine("Rendering Service Handled ZoneDestroyed Event");
    }

    public void Handle(ZoneCreatedEventArgs args)
    {
        Console.WriteLine("Rendering Service Handled ZoneCreated Event");
    }
}

Services need to do other things as well as handle events (but might not have other interfaces as they are not required). Some services need to be a singleton, and the handling of events should respect the singleton registration. Thus a call to container.Resolve(IHandles<>) should return the Singleton type for that service and not make multiple instances. These services are gathering events from multiple sources and therefore need to maintain internal state before sending them off elsewhere. Therefore different eventhandlers calling different services need to be sent to the same underlying instance.

I would like to be able to add IHandles interfaces to any service, and have it picked up automatically without having to fiddle with IOC mappings every time. Ideally service types should be added using convention based mapping as well.

So far I've been working on this for two days. I gave up trying to achieve it with structuremap. Now I'm trying DryIOC - but finding it to be even more difficult to understand and get right.


回答1:


It is pretty easy to do in DryIoc (I am an owner). Here I will speak about V2 RC version.

Given that you've replaced IContainer dependency with IResolver which is automatically injected:

var container = new Container();

container.Register<IEventDispatcher, DryIocEventDispatcher>();
container.RegisterMany<ScoringService>(Reuse.Singleton);
container.RegisterMany<RenderingService>();

var eventDispatcher = container.Resolve<IEventDispatcher>();

eventDispatcher.Dispatch(new ZoneDestroyedEventArgs());
eventDispatcher.Dispatch(new ZoneCreatedEventArgs());

RegisterMany will take care of handlers being reused as Singleton and will return the same instance for both Handles<> interfaces.

Additionally you may use RegisterMapping to add/map IHandles<> service to already registered implementation.

DryIoc has even more to help with EventAggregator implementation.

Also here is solution for problem similar to yours.

The gist with your working example.



来源:https://stackoverflow.com/questions/32631325/dryioc-event-aggregator

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!