NuGet library to support CQS pattern based project with Autofac implementation
Library is created for personal purposes but I decided that it can get useful for someone else so feel free to use.
Library allows to provide simple command query separation inside project using AutoFac library.
Commands are executed without results in return.
using Rebar.Core.Command
private ICommandDispatcher _dispatcher;
public Execute(ICommandDispatcher dispatcher)
{
_dispatcher = dispatcher;
}
...
var command = new SampleCommand("John");
_dispatcher.Execute(command);
public class SampleCommand : ICommand
{
public string Name { get; set; }
public SampleCommand(string name)
{
this.Name = name;
}
}
public class SampleCommandHandler : ICommandHandler<SampleCommand>
{
public void Execute(SampleCommand command)
{
command.Name // John
...
}
}
Queries are executed and return defined class object
using Rebar.Core.Query
private IQueryDispatcher _dispatcher
public Execute(IQueryDispatcher dispatcher)
{
_dispatcher = dispatcher;
}
...
var query = new SampleQuery(10);
var result = _dispatcher.Execute(query); // result = { SubstractionResult: 4 }
public class SampleQuery : IQuery<SampleQueryResponse>
{
public int BaseNumber { get; set; }
public SampleQuery(int number)
{
this.BaseNumber = number;
}
}
public class SampleQueryResponse : IQueryResponse
{
public int SubstractionResult { get; set; }
public SampleQueryResponse(int result)
{
this.SubstractionResult = result;
}
}
public class SampleQueryResponseHandler : IQueryHandler<SampleQuery, SampleQueryResponse>
public SampleQueryResponse Execute(SampleQuery query)
{
var substraction = query.BaseNumber - 6;
return new SampleQueryResponse(substraction);
}
ICommandHandler<ICommand> => IAsyncCommandHandler<ICommand>
public class SampleCommandHandler : IAsyncCommandHandler<SampleCommand>
{
public void ExecuteAsync(SampleCommand command, CancellationToken token) {}
}
...
_dispatcher.ExecuteAsync(command);
IQueryHandler<IQuery, IQueryResponse> => IAsyncQueryHandler<IQuery, IQueryResponse>
public class SampleQueryResponseHandler : IAsyncQueryHandler<SampleQuery, SampleQueryResponse>
{
public Task<SampleQueryResponse> ExecuteAsync(SampleQuery query, CancellationToken token) {}
}
...
_dispatcher.ExecuteAsync(query);
In startup.cs
include following line to include Rebar.Core in service collection.
using Rebar.Core.Extensions;
...
builder.AddRebarCore();
Next in AutoFac module files declare registering commands and/or queries.
❗ Important: Handlers are name sensitive. They should end with "QueryHandler" or "CommandHandler" otherwise they won't be recognized.
using Rebar.Extensions;
public class AppModule : Module
{
protected override void Load(ContainerBuilder builder)
{
var executingAssembly = GetExecutingAssembly();
// register commands within assembly
builder.RegisterCommandHandlers(executingAssembly);
// register queries within assembly
builder.RegisterQueryHandlers(executingAssembly);
// register both queries and commands within assembly
builder.RegisterAll(executingAssembly);
}
}
ContainerBuilder RegisterCommandHandlers(self ContainerBuilder builder, ExecutingAssembly assembly, InstanceTypes instanceType, object[] lifeTimeScopeTags)
Registers commands within assembly.
builder
ContainerBuilder
description: Extension for AutoFacContainerBuilder
assembly
ExecutingAssembly
description: Assembly that contains commands definitions- (optional)
instanceType
InstanceTypes
description: Instance lifecycle type for commands.
default:InstanceTypes.LifetimeScope
- (optional)
lifeTimeScopeTags
object[]
description: Tag applied to matching lifetime scopes. Optional for request scope, required for matching lifetime scope.
default:null
ContainerBuilder RegisterQueryHandlers(self ContainerBuilder builder, ExecutingAssembly assembly, InstanceTypes instanceType, object[] lifeTimeScopeTags)
Registers queries within assembly.
builder
ContainerBuilder
description: Extension for AutoFacContainerBuilder
assembly
ExecutingAssembly
description: Assembly that contains queries definitions- (optional)
instanceType
InstanceTypes
description: Instance lifecycle type for queries.
default:InstanceTypes.LifetimeScope
- (optional)
lifeTimeScopeTags
object[]
description: Tag applied to matching lifetime scopes. Optional for request scope, required for matching lifetime scope.
default:null
ContainerBuilder RegisterAll(self ContainerBuilder builder, ExecutingAssembly assembly, InstanceTypes instanceType, object[] lifeTimeScopeTags)
Registers both commands and queries within assembly.
builder
ContainerBuilder
description: Extension for AutoFacContainerBuilder
assembly
ExecutingAssembly
description: Assembly that contains commands and queries definitions- (optional)
instanceType
InstanceTypes
description: Instance lifecycle type for command and queries.
default:InstanceTypes.LifetimeScope
- (optional)
lifeTimeScopeTags
object[]
description: Tag applied to matching lifetime scopes. Optional for request scope, required for matching lifetime scope.
default:null