Как использовать TinyMessenger (агрегатор событий) с DI-контейнером

Я искал легкий агрегатор событий для .Net и наткнулся на TinyMessenger (https://github.com/grumpydev/TinyMessenger/wiki). Кажется, он выполняет ту работу, которую я хочу, но я не могу понять, как использовать его с контейнером DI, например, Structuremap, который я собираюсь использовать.

Вот мой простой тестовый код

class Program
{
    static void Main(string[] args)
    {
        var messageHub = new TinyMessengerHub();
        var salesMadeHandler = new SalesMadeHandler(messageHub);
        messageHub.Publish(new SaleMadeEvent() {Id = Guid.NewGuid(), Total = 100});
        Console.ReadKey();
    }
}

class SalesMadeHandler
{
    private readonly ITinyMessengerHub _messengerHub;
    public SalesMadeHandler(ITinyMessengerHub messengerHub)
    {
        _messengerHub = messengerHub;
        _messengerHub.Subscribe<SaleMadeEvent>(Handle);
    }

    public void Handle(SaleMadeEvent message)
    {
        Console.WriteLine("Message Recieved with ID: " + message.Id);
    }
}

как вы можете видеть в приведенном выше коде, у меня есть класс SalesMadeHandler, который подписывается на событие в своем конструкторе. Я понимаю, что я должен иметь возможность пометить этот класс интерфейсом, и контейнер DI должен автоматически создать его экземпляр и использовать его для обработки сообщений. Однако в этом случае я должен иметь уже созданный экземпляр перед публикацией сообщения из-за механизма подписки.

Я думаю, что мне не хватает ключевого момента здесь с агрегатами событий, не могли бы вы посоветовать, что мне не хватает?


person Afraz Ali    schedule 12.11.2015    source источник


Ответы (1)


Используйте TinyIoC в качестве контейнера DI. Он отлично работает для мессенджера и создаст мессенджер для вас. Чтобы использовать его, необходимо установить TinyIoC nuget, открыть файл, добавленный в ваш проект, и раскомментировать #define TINYMESSENGER в области Preprocessor Directives файла.

Теперь вы можете использовать TinyIoC для разрешения своих экземпляров, а контейнер DI создаст для вас мессенджер и передаст его вашему обработчику...

static void Main(string[] args)
{
    var salesMadeHandler = TinyIoCContainer.Current.Resolve<SalesMadeHandler>();

    var messageHub = TinyIoCContainer.Current.Resolve<ITinyMessengerHub>();
    messageHub.Publish(new SaleMadeEvent() { Id = Guid.NewGuid(), Total = 100 });

    Console.ReadKey();
}
person Markus Gilli    schedule 12.11.2015
comment
Спасибо за ваш комментарий, Маркус, меня смущает необходимость создания ссылки на salesMadeHandler в коде. Если я публикую это сообщение в разных ограниченных контекстах, я не могу создать экземпляр класса обработчика, используя какой-либо контейнер внедрения зависимостей. Вместо этого я понимаю, что когда я публикую событие/сообщение, сама структура должна вызывать экземпляр обработчика, верно? - person Afraz Ali; 12.11.2015
comment
Публикация события не создаст для вас ни одного экземпляра. Мессенджер будет доставлять только при подписке. Поэтому вам нужно создать хотя бы один обработчик. TinyIoC поддерживает одноэлементную регистрацию, но будьте осторожны при ее использовании, это может привести к путанице с зависимостями... Ознакомьтесь с документацией по TinyIoC, чтобы узнать, как создать: github.com/grumpydev/TinyIoC/wiki/ - person Markus Gilli; 12.11.2015