Bolt.RequestBus : Introduction – Part 1

Recently published a nuget package named Bolt.RequestBus. The main purpose of this library is to easily dispatch request (Command, Query) and publish events. This allow to keep your controller thin and loosly coupled. For each request the library also raise some events that help you to push the events to eventstore with minimum code. Also support filter to allow you add multiple filters and modify the response after response completed. All operations support async.

A sample application has been provided in github that shows how to use this library for read/write/eventsourcing scenario. I am planning to write a series of blog posts that show how to integrate this library in your application and how to use different features. A sample application available in github. You can download the sample application from here.

Provide a feature to allow user create a new book

Before implementing a feature lets trying to define what your input and whats the output. In this case the input should be title, price, author etc of a book that needs to be created. For output I need to know the id of the book that created. I define the input in a class name “CreateBookRequest” and that is my input and output will be a Guid that will tell the id of the new book created. So i define the request and controller endpoint and ask request bus to send this request and return and id as guid. “this.ResponseResult” is an extension method and to find out more check “ResponseExtensions.cs” file in source code.

public class CreateBookRequest : Bolt.RequestBus.IRequest
{
    public string Title { get; set; }
    public decimal Price { get; set; }
    public string Author { get; set; }
}

[RoutePrefix("v1/books")]
public class GetBooksController : ApiController
{
    private readonly IRequestBus bus;

    public GetBooksController(IRequestBus bus)
    {
        this.bus = bus;
    }

    [Route]
    [HttpPost]
    public IHttpActionResult Post([FromBody] CreateBookRequest request)
    {
        var response = bus.Send<CreateBookRequest, Guid>(request);

        return this.ResponseResult(response, id => Url.BookById(id));
    }
}

Now if you run this endpoint you will get an error. Because you didn’t register any handler for this request and response. So lets implement a handler.

public class CreateBookRequestHandler : RequestHandlerBase<CreateBookRequest, Guid>
{
    private readonly ILogger logger;
    private readonly IBookRepository repository;
    private readonly IMapper mapper;

    public CreateBookRequestHandler(ILogger logger, IBookRepository repository, IMapper mapper)
    {
        this.logger = logger;
        this.repository = repository;
        this.mapper = mapper;
    }

    protected override Guid Process(CreateBookRequest msg)
    {
        var id = Guid.NewGuid();

        var record = mapper.Map<BookRecord>(msg);

        record.Id = id;

        repository.Insert(record);

        logger.Info($"New book created with id {id} and title {msg.Title)");

        return id;
    }
}

Okay handler created now register this handler in your ioc container. Typically in your system you might have many requesthandlers and everytime you create a handler you have to register this in your ioc container. So make your life easy you can your convention to register you handler automatically and here how you can do this.

Just want to add something about IStartUpTask. I use this class to run a list of task on application startup. e.g Mapping configuration setup of automapper. Generally i create mapper configuration close to the model and this technique allow me to load them application startup automatically (Check also startup.cs file in sample app).

public class ConventionBasedModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        var assemblies = new[]
        {typeof (Startup).Assembly};

        builder.RegisterAssemblyTypes(assemblies)
            .Where(a => a.IsClass && 
                (a.Name.EndsWith("Handler"))
            .AsImplementedInterfaces();

        builder.RegisterAssemblyTypes(assemblies)
            .AssignableTo<IStartUpTask>()
            .AsImplementedInterfaces();
        
    }
}

That’s it you successfully created a new feature and your should able to create a new book. Next part I will show how you can easily add validation for your request.

Here are links for other posts in these series

Happy coding 🙂

Advertisements

4 thoughts on “Bolt.RequestBus : Introduction – Part 1

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s