Skip to content

Mediator (CQRS)

Ivan edited this page Sep 2, 2020 · 7 revisions

Query

Query is a class or struct, that implemented IQuery generic interface. TResult - type of query result.

Add query pipeline

var dependencyProvider = new DependencyCollection()
    .AddEmitter()                           // mediator infrastructure
    .AddQueryPreProcessor<PreProcessor>()   // one or more pre-processor(s)
    .AddQueryProcessor<Processor>()         // one processor
    .AddQueryPostProcessor<PostProcessor>(DependencyLifetime.Scoped)
    .AddScoped(typeof(IQueryBehaviour<>), typeof(MeasureBehaviour<>))
    .BuildProvider();

Add action query processor

var dependencyProvider = new DependencyCollection()
    .AddEmitter()
    .AddQueryProcessor<Query, Boo>(query => closure.Get(query.Payload))
    .BuildProvider();

Ask a query

var emitter = dependencyProvider.GetRequired<IEmitter>();
Boo result = await emitter.Ask<Query>(new Query(booId));

Or you can ask query without memory allocation for boxing (if you use a struct):

var emitter = dependencyProvider.GetRequired<IEmitter>();
Boo result = await emitter.Ask<StructQuery, Boo>(new StructQuery(booId));

Notification

Notification is a class or struct, that implemented INotification interface.

Add notification processor

var dependencyProvider = new DependencyCollection()
    .AddEmitter()
    .AddNotificationProcessor<NotificationProcessor>()
    .BuildProvider();

Publish notification

var emitter = dependencyProvider.GetRequired<IEmitter>();
await emitter.Publish(new Notification());

If you don't know a notification type, use method Send:

var emitter = dependencyProvider.GetRequired<IEmitter>();
INotification notification = notificationBuilder.Create(someModel);
await emitter.Send(notification);

Use ParallelAttribute with your notification class for use parallel notification processing.

Command

Command is a class or struct, that implemented ICommand interface.

Add command pipeline

var dependencyProvider = new DependencyCollection()
    .AddEmitter()
    .AddCommandBehaviour<Behaviour>()
    .AddCommandProcessor<PreProcessor>()
    .AddCommandProcessor<Processor>()
    .AddCommandProcessor<PostProcessor>()
    .BuildProvider();

Add an action command processor

var dependencyProvider = new DependencyCollection()
    .AddEmitter()
    .AddCommandProcessor<Command>(cmd => closure.AddElement(new Boo(cmd.Id)))
    .BuildProvider();

Execute command

var emitter = dependencyProvider.GetRequired<IEmitter>();
await emitter.Execute(new Command());

If you don't know a command type, use method Send:

var emitter = dependencyProvider.GetRequired<IEmitter>();
ICommand command = commandBuilder.Create(someModel);
await emitter.Send(command);