Bolt.IocScanner – DotNet Core Dependency Injection with Convention and Attribute

Dependency injection is a common practice for any application development now a days. Thats why dotnetcore comes with inbuilt dependency injection provider. Which makes the whole development experience much better for any applications event if you build a console or serverless lambda/function application.

And here how we generally use it in a typical mvc applicaton.

Your initial startup.cs file is as below:

    // file: ~/Startup.cs
    public void ConfigureServices(IServiceCollection srvices)
    {
        services.AddMvc();
    }

Then you define your controller say which allow you to manage books:

    // file: ~/Controllers/BooksController.cs
    public class BooksController : Controller
    {
        private readonly IBooksService _booksService;

        public BooksController(IBooksService booksService)
        {
            _booksService = booksService;
        }

        ...
    }

Your books service class might be as below:

    // file: ~/Services/BooksService.cs
    public class BooksService : IBooksService
    {
        private readonly IBooksRepository _repo;

        public BooksService(IBooksRepository repo)
        {
            _repo = repo;
        }
        ....
    }

Your books repository might be as below:

    // file: ~/Repositories/BooksRepository.cs
    public class BooksRepository : IBooksRepository
    {
        publi BooksRepository(IDatabase db)
        {
            ....
        }
    }

Now you run your application it will fail. Because you didn't register all these classes in your IOC. So now you have to go back ot Startup file and update as below:

    // file: ~/Startup.cs
    public void ConfigureServices(IServiceCollection srvices)
    {
        services.AddScoped<IDatabase.SqlDatabase>();
        services.AddTransient<IBooksProxy,BooksProxy>();
        services.AddTRansient<IBooksService,BooksService>();

        services.AddMvc();
    }

This just gives you an idea, but in real life this is a circle. Everytime you add a new feature or refactory you have to come to startup file and update code to register any new classes you added. This is a pain. At the same time its a code smell also as your startup file changed almost for every class you add in your application that needs to be injected.

<!–more Keep on reading!–>

So in ideal world I like my classes automatically bind against the interface so I don't need to write those registration codes in startup file. In other word I don't need to touch the Startup file during the development of the application. At the same time I like to get flexibility to control what the class instance lifecycle should be if required. So introducing Bolt.IocScanner which allow me to do the way I like to use IOC container during development. You need to add nuget package Bolt.IocScanner in your application and add one line in your startup class. After that whenever you add new class that imeplement an interface will be registered automatically. You never need to touch startup file.

Your startup file should be as below:

    // file: ~/Startup.cs
    public void ConfigureServices(IServiceCollection srvices)
    {
        // Just add following line to scan and register automatically
        services.Scan<Startup>();

        services.AddMvc();
    }

Okay I am convniced. But what about…

Can I scan mutiple assemblies?

Yes you can. Here is an example:

    public void ConfigureServices(IServiceCollection services)
    {
        services.Scan(new []{
            typeof(BookStore.Web.Startup).Assembly,
            typeof(BookStore.Infrastructure.ISerializer).Assembly
        });
    }

How can I bind a class to self without using an inteface?

If a class doesn't implement any interface then the lib doesn't bind it automatically. You have to put AutoBind attribute to bind a class without interface. Then the library bind that class to self with lifecycle instructed in the attribute. See example below:

    [AutoBind]
    public class BooksProxy
    {
        public Task Get(string id)
        {
            // your code here ...
        }
    }

    public class BooksController : Controller
    {
        private readonly BooksProxy _proxy;

        public BooksController(BooksProxy proxy)
        {
            _proxy = proxy;
        }
    }

How I can control the lifecycle of the bindings?

By default all bindings use transient lifecycle. If you want different lifecycle then you need decorate your class with an attribute as below and can mention what lifecycle you like the class to bind.

    [AutoBind(LifeCycle.Scoped)]
    public class BooksProxy
    {

    }

    // or if you like to register as singleton

    [AutoBind(LifeCycle.Singleton)]
    public class ConnectionPool
    {

    }

How I can exclude some classes from automatic binding?

Theres four ways you can do this.

You can decorate the class that you want to exclude using an attribute

    [SkipAutoBind]
    public class ThisClassNotBind
    {

    }

you can add the class type as exclude items of scan options as below

    public void ConfigureServices(IServiceCollection services)
    {
        services.Scan(new IocScannerOptions
        {
            TypesToExclude = new[] { typeof(ThisClassNotBind) }
        });
    }

you can tell in option that only bind when an "AutoBind" attribute provided. In that case any class in assemblies doesn't have "AutoBind" attribute will not be registered in ioc.

    public void ConfigureServices(IServiceCollection services)
    {
        services.Scan(new IocScannerOptions
        {
            SkipWhenAutoBindMissing = true
        });
    }

you can even pass your own logic to exclude any types using a func as below

    public void ConfigureServices(IServiceCollection services)
    {
        services.Scan(new IocScannerOptions()
            .Exclude(t => t.Name.Equals("Startup")));
    }

Does it bind to all implemented interfaces?

Yes if a class implement more than one interfaces the lib bind the class against all interfaces. In case of Singleton and Scoped lifecycle all interface bind against same instance. For example:

    [AutoBind(LifeCycle.Singleton)]
    public class Implementation : IProvideName, IProvidePrice
    {
    }

Now if you request for IProvideName and IProvidePrice both case the service provider will return same instance of Implementation throughout the whole life of the application.

Same applies for Scoped lifecycle but in that case the behaviour is true for same scope. For new scope a new instance of Implementation will be provided by service provider.

How can I ask to register using TryAdd instead

Sometimes you want to change the registration of your implementation when you setup Ioc in your test projects. In that case sometimes its easy to achieve if we use TryAdd instead of Add. So yes you can tell to use TryAdd instead of Add when register your implementation as below:

    [AutoBind(UseTryAdd = true)]
    public class BooksProxy
    {

    }

I reckon I did cover most of the things the library supports. Enjoy using Bolt.IocScanner.

Happy Coding 🙂

An Event Driven Approach for Building Website using ASP.NET Core

First of all this post not only related to asp.net core and can apply to previous versions of asp.net MVC. But the sample codes are based on asp.net core RC2.

One of the most challenging part of developing application is to keep the code base healthy as it grows with features. We start with greenfield project. Everything shiny and works fine. The business grows and we need to add lot of new functionalities. One day we found that the application is no longer maintainable. We can’t easily add new feature anymore and that application become legacy again.

That’s why micro services become more popular nowadays. This blog post is not about micro services but how we can write maintainable application with isolated features using CQRS and event driven approach.

As an example take a look at following home page of an imaginary e-commerce site that sell books.

sample-site

 

For home page we want to load following features from server sides.

  1. Category menu
  2. Latest Books
  3. Books of the week
  4. Books saved as favourite or not

The reason why we decide to load them from server side is as below:

  1. We want to load home page quickly without any further delay from client side. So the page is immediately usable rather than displaying a spinner and wait to load all data. If you need further details read some articles on page speed 🙂 The discussion about that is out of this blog post scope.
  2. Other important reason is they have SEO value.
  3. Some features like recently viewed can be loaded later using client script as they most likely position below fold of initial screen. That means not inside viewport of first page load. And this doesn’t have SEO value as the data depends on current users last visited books.
  4. Books saved or not can be loaded using javascript. But here we will load from server side so that the information is immediately visible rather then script load later. We try to load most things from server that will be above view fold. Visible to user screen on first load.

First Approach : One big ViewModel

So how can achieve this? We can load all data of home page in one go. So we can define a viewmodel for page as below and load the viewmodel from homecontroller.

    public class HomeViewModel
    {
        public string CurrentUserFullName { get; set; }
        public int TotalBooksInCart { get; set; }
        public IEnumerable<BookListItemDto> LatestBooks {get; set;}
        public IEnumerable<BookListItemDto> BooksOfTheWeek {get; set;}

        public IEnumerable<CategoryMenuItemDto> CategoryMenu {get; set;}
    }

    public class CategoryMenuItemDto
    {
        public string Slug {get; set;}
        public string Name {get; set;}
        public string TotalBooks {get; set;}
    }

    public class BookListItemDto
    {
        public string Id {get; set;}
        public string Title {get; set;}
        public string Slug {get; set;}
        public string ImageUrl {get; set;}
        public decimal Price {get; set;}
        public bool IsSaved {get; set;}
    }

    public class HomeController : Controller
    {
        private readonly IRequestBus bus;
        public HomeController(IRequestBus bus)
        {
            this.bus = bus;
        }

        public async Task<IActionResult> Index(){
            var vm = await bus.SendAsync<HomePageQuery,HomeViewModel>(new HomePageQuery());
            return View(vm.Value);
        }
    }

    public class HomePageQueryHandler : AsyncRequestHandlerBase<HomePageQuery,HomeViewModel>
    {
        // hide constructor code

        public async Task<HomeViewModel> HandleAsync(HomePageQuery query)
        {
            var taskLoadCategoryMenu = categoryApiProxy.GetAsync();
            var taskLoadLatestBooks = booksApiProxy.GetLatestBooksAsync();
            var taskLoadBooksOfTheWeek = booksApiProxy.GetBooksOfTheWeekAsync();
            var taskLoadCart = cartApiProxy.GetCartAsync();
            // Just to remove complexity assuming user logged in
            var taskLoadProfile = userProfileApiProxy.GetProfileAsync(_userContext.UserId);

            await Task.WhenAll(taskLoadCategoryMenu, taskLoadLatestBooks, taskLoadBooksOfTheWeek, taskLoadCart, taskLoadProfile);

            return new HomeViewModel
            {
                CurrentUserFullName = taskLoadProfile.Result.Name,
                TotalBooksInCart = taskLoadCart.Result.Items.Count(),
                LatestBooks = LoadBooksListWithSavedStatus(taskLoadLatestBooks.Result, taskLoadCart.Result),
                BooksOfTheWeek = LoadBooksListWithSavedStatus(taskLoadBooksOfTheWeek.Result, taskLoadCart.Result),
                CategoryMenu = taskLoadCategoryMenu.Result
            };
        }
    }

The problem with this approach is it loads all data for a page in one big viewmodel. Some of them like total items in cart, category menu we need to do again in other pages. And our query handler getting too much responsibility with lots of code. This code will grow day by day when we add more features in home page. Its going to be a maintenance problem in future as it violates single responsibility principle. One good thing about this approach I can do all api calls in parallel. That means I can load all data from server side with minimal time which is great for performance.

Second Approach: Use of View Component or Render Action

In this approach we will use Render action to load different features and keep them independent, rather than using a big viewmodel for everything on a page.

    public class HomeController : Controller
    {
        public Task<IActionResult> Index()
        {
            return View();
        }
    }

    public class LatestBooksViewComponent : ViewComponent
    {
        private readonly IRequestBus bus;
        public LatestBooksViewComponent(IRequestBus bus)
        {
            this.bus = bus;
        }
        public async Task<IViewComponentResult> InvokeAsync()
        {
            var vm = await bus.SendAsync<LatestBooksQuery,IEnumerable<BookListItemDto>>();
            return View(vm);
        }
    }

    public class LatestBooksQueryHandler : AsyncQueryHandlerBase<LatestBooksQuery, IEnumerable<BookListItemDto>>
    {
        // constructor code removed

        public Task<IEnumerable<BookListItemDto>> HandleAsync(LatestBooksQuery query)
        {
            return booksApiProxy.GetLatestBooksAsync();
        }
    }

Sample html code for index.cshtml for home.

<div class="page-shell">
    <section class="two-col">
        <section class="col-1">
            @await Component.InvokeAsync("CategoryMenu")
        </section>
        <section class="col-2">
            @await Component.InvokeAsync("LatestBooks")
            @await Component.InvokeAsync("BooksOfTheWeek")
            @await Component.InvokeAsync("RecentlyViewed")
        </section>
    </section>
</div>

As you can see this is nice and clean approach. Each feature can be individual component and load required data by itself without any direct dependency on home page. Now home page doesn’t need to load all data for all the feature required in this page. We can load this features in other pages also without changing any code in page itself as they don’t have any dependencies on container page.

But one big problem with this approach is that now we lost the performance of first approach. Because all data e.g latest books, books of the week, categories now loading from api one after another. So total load time of page now should be slower than first approach.

So we need a solution that has all the benefit of second and first approach. Let’s see the third approach.

Third Approach: Events to the rescue

Let’s declare an event and publish the event from homecontroller.

public class HomePageRequestedEvent : IEvent { }

public class HomeController : Controller
{
	private readonly IRequestBus bus;

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

	public async Task<IActionResult> Index()
	{
		await bus.PublishAsync<HomePageRequestedEvent>(new HomePageRequestedEvent());
		return View();
	}
}

public class LatestBooksViewComponent : ViewComponent
{
    private readonly ILatestBooksProvider provider;

    public LatestBooksViewComponent(ILatestBooksProvider provider)
    {
        this.provider = provider;
    }
    

    public IViewComponentResult Invoke()
    {
        var vm = provider.Get();

        return View("~/Features/Home/LatestBooks/Views/LatestBooks.cshtml", vm);
    } 
}

Now write a handler that will populate latest books view model and store the value using provider.

public class LoadLatestBooksOnPageLoad : IAsyncEventHandler<HomePageRequestedEvent>
{
    private readonly ILatestBooksProvider provider;
    private readonly IRestClient restClient;
    private readonly ILogger logger;
    private readonly IOptions<ApiSettings> settings;

    public LoadLatestBooksOnPageLoad(ILatestBooksProvider provider,
        IRestClient restClient, 
        ILogger logger,
        IOptions<ApiSettings> settings)
    {
        this.provider = provider;
        this.restClient = restClient;
        this.logger = logger;
        this.settings = settings;
    }
    
    public async Task HandleAsync(HomePageRequestedEvent eEvent)
    {
        var response = await ErrorSafe.WithLogger(logger)
            .ExecuteAsync(() => restClient.For($"{settings.Value.BaseUrl}/books/latest")
                .AcceptJson()
                .Timeout(1000)
                .RetryOnFailure(2)
                .GetAsync<IEnumerable<BookDto>>());

        provider.Set(response.Value?.Output);
    }
}

That’s it, You can write other features of home page like BooksOfTheWeek, CategoryMenu etc using same event handler pattern and all of them will load in parallel. That means performance gain without compromising loosely coupled architecture of your system.

A sample application available to check here.

Happy coding 🙂

Bolt.RequestBus : More On Events – Part 5

This is fifth part of the series. In our previous post we discuss about filters and how to use them in your application. If you don’t know what Bolt.RequestBus is please read the first part of this series. We did discuss about events in part 3 of this series. In this post we gonna find out about default events raised by the library and how you can use them instead of publishing events by yourself from RequestHandler. Continue reading

Bolt.RequestBus : How to use Filters – Part 4

This is fourth part of the series. In our previous post we discuss about how to publish and handle events for a request. If you don’t know what Bolt.RequestBus is please read the first part of this series. In this part I am trying to show how you can use filter in application and reduce the complexity of request handler. You can add more than one filter for any request. Filter may not always necessary but in some cases you might find this technique very helpful. This will help to reduce the complexity of Handler as you can divide the responsibility to filters. Generally filters more appropriate for Query when you reading data from system, but you need to read from different sources or do complex calculation on result. Continue reading

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 Continue reading

Redis Pub/Sub : Keep your InMemory Cache Fresh

Redis has a very nice feature called Pub/Sub. You can publish an event when a key value change and other applications can subscribe to this event. You can use this feature to keep your in memory cache always fresh.

Problem

InMemory cache is the fastest cache and very critical for performance of your application. But the problem with in memory cache is its not possible to clear your cache when the data change in original source (i:e database).

I am trying to explain the whole idea using an example. Suppose your application displays list of categories with count (number of books in each category) in websites to allow users browse books by category. As categories do not change that much and we don’t add books every minute so your team decided to put this in memory cache for 30 minutes. Which works fine but sometimes when you add a new book under a category the count didn’t update in website immediately as they cached in memory for 30 minutes. The update could take maximum 30 minutes to display in browser. Because your application deployed in web farm all individual instance has its own in memory cache of this data.
Continue reading

AutoFixture – Make your tests slim and maintainable

Autofixture is an excellent library that can generate your tests data so as a developer you spent more time on what to test rather than how to setup data for tests. As you write less code to create the object you going to test so the code become more maintainable. For the example codes I am using following libraries:
1. XUnit – As unit testing framework
2. AutoFixture – A framework to generate test data
3. NSubstitute – A mocking library
4. Shouldly – A fluent assertion library.
Continue reading

Multilevel Caching using Bolt.Cache – InMemory and Redis

Caching is a very important part of scaling your website. In this blog post I am trying to show how you can implement a two level caching. One Redis for distributed caching and the other one is inmemory caching. So the idea is first you look whether data exists in memory. If not then check whether the data exists in Redis. If not then load from your Sql Data source. And then save this in memory and Redis. So for next request we can serve the data from memory, if not from Redis. Continue reading