A Gentle Introduction to Onion Architecture in ASP.NET MVC – Part 2

In part 1 of this series we discussed what an onion architecture application would look like and discussed the technologies that we can leverage in .Net 4 in order to make that work. In this section we’ll go over how the project is structured, including spending a bit of time looking at how the IoC container is configured. This being a simple application the configuration is significantly easier to understand than it can be in more complex applications.

Project Structure

The application consists of 4 projects: Core, Infrastructure, Infrastructure.Tests, and Web. Each one of these projects has a unique purpose and it behooves all developers to ensure that they don’t mix concerns between projects.

Core Project

The core project is responsible for defining all interfaces for all services which will be implemented in the infrastructure layer, and it also is responsible for having all domain models. In Entity Framework Code First projects, the EF Entity Models can exist in Core. The models that exist in the sample application are not “true” domain models, instead they are just POCO representations

Infrastructure and Test Project

The infrastructure project is responsible for the implementation of all of the services defined in the Core Project. One of the critical distinctions between onion architecture and traditional layered applications is that the data access code (if there is any) will live in an infrastructure style project instead of living in the base/core layer. In the sample application the Infrastructure project only calls out to third-party services. The test project only tests the behavior of the composite service as I have not written this application in a sufficiently decoupled fashion to pass in the RestClient and ideally an abstraction would also be built around the ConfigurationManager

Web Project

As the name probably implies, this is where the “web” parts of the application go, including controllers, views, front-end assets, etc. For this application front end assets are just managed by downloading and saving them into /Scripts, and then everything is manually wired up using the BundleConfig.cs in App_Start. The interactivity within the application is achieved by using a little bit of jQuery.

Dependency Resolution

This application exposes 4 services in total, but only has 2 interfaces. This is due to the fact that the CompositeBounceCheckerService is composed of both MailgunService and SendGridService, hence all three of them share the same interface. The final service, the SuppressionListCheckService just consumes the CompositeBounceCheckerService. This final layer of indirection isn’t, strictly speaking, necessary, however it does afford the ability easily pass one of the service-specific IThirdPartyBounceService services as its dependency if we only wanted to check for suppression in a single ESP. The DefaultRegistry below shows how to get that all setup.

            For<IThirdPartyBounceService>().Use<CompositeBounceCheckerService>()
                .EnumerableOf<IThirdPartyBounceService>().Contains(x =>
                {
                    x.Type<SendGridService>();
                    x.Type<MailgunService>();
                });

This code basically tells StructureMap to scan all registered assemblies (all assemblies listed in the Scan call above this) and register the SendGridService and MailgunService as services within the composite service.

StructureMap is capable of doing a lot more, such as having custom life-cycles for certain services or handling weird object hierarchies (you can do a lot more than just have interfaces and services).

Testing

Testing is fairly direct as we just mock out the services that feed into the service we want to test (generally known as the “SUT” or the System Under Test). One easy example of a test is this:

        [Fact]
        public void Get_Bounces_Returns_A_List_Of_View_Models()
        {
            // Arrange
            var returnList = new List<SuppressedEmailViewModel>
            {
                new SuppressedEmailViewModel
                {
                    AddedOn = DateTime.Now,
                    EmailAddress = "[email protected]",
                    EmailServiceProvider = EspEnum.UNKNOWN,
                    ErrorCode = string.Empty,
                    ErrorText = string.Empty
                }
            };

            var mockService1 = new Mock<IThirdPartyBounceService>();
            mockService1.Setup(x => x.GetBounces()).Returns(returnList);
            // Initialize the composite service with an array of one third party service.
            var compositeService = new CompositeBounceCheckerService(new[] { mockService1.Object });

            //Act and Assert
            var result = compositeService.GetBounces();

            Assert.Equal(returnList, result);
            mockService1.Verify(x => x.GetBounces(), Times.Once);
        }

The code above will first: create data for the Mock to return, then: create and setup the mock, then: inject it into the service, then: call the service, and finally: make sure that the behavior of the service was correct. Having a robust suite of tests allows us to change the implementation of any of the services and still verify that the output is correct.

When writing tests, I generally follow the AAA pattern (Arrange, Act, Assert) and leave comments in the code where those things are happening as an easy way to make sure that my tests are structured in a consistent fashion.

That’s all for now folks. I hope that this two part series on the onion architecture made the benefits of using it a bit more clear.

Please, check out the code on Github, and drop me a line if you have any questions!

A Gentle Introduction to Onion Architecture in ASP.NET MVC – Part 1

Welcome to part one of a multi part series on Enterprise Application in .Net Core! In this series we’ll go over everything that is necessary to build a best in breed enterprise application with the Onion Architecture at its core. The word enterprise is integral in describing the software being described as it is going to be software which is capable of being extended year after year in a clean fashion while allowing things to stay DRY and testable. We’ll cover the following:

  1. System to Design
  2. Initial Architecture and Architectural Considerations
  3. Proper Abstractions Around Each Layer of the “Onion”
  4. Unit Testing

This series of posts isn’t going to exhaustively walk you through every decision that may need to be considered (i.e. we’ll only very briefly discuss localization). My intention with these posts is to put forth my ideas of what a solid architecture looks like. With that being said, the application we are going to design is called “Block List Checker” which is an application which will allow one or more Email Service Providers (ESPs) such as Mailgun, SendGrid, etc. to be queried simultaneously to return a list of all email addresses which are on a suppression list. This is a very simple application which is intentionally somewhat over-engineered for the purposes of illustrating the various components of the system.

Inversion of Control and Dependency Injection

In order to design this software appropriately there are several tools that will need to be incorporated into the solution. The first (and arguably the most important) of these is StructureMap a .Net-friendly IoC/DI Container. For those not familiar: IoC (or Inversion of Control) and DI (or Dependency Injection) are design patterns which help make code much more testable. They do this by “inverting” the dependency chain. The way this plays out in MVC applications is that controllers will be injected with all of the dependencies that all of the services which are used by those controllers require. The IoC container will basically maintain a mapping of interfaces to services and, at runtime, will provide the controller with an instance of the service requested. Due to the fact that this effectively requires loose-coupling between components, writing unit tests becomes much easier (note that the description of IoC here is just barely skimming the surface, entire books have been written on this subject).

Unit Testing

Because this application is so simple, I have opted not to write comprehensive tests around it, however I have written a few tests just to demonstrate using xunit with this application and how the loose coupling allows the testing to be achieved.

Known Issues

This application is very basic and the UI could use a bit of love. It currently targets Asp.Net MVC5 instead of .Net Core MVC6 due to the fact that I prefer writing API access code using RestSharp, and that currently doesn’t seem compatible with .Net Core. I may release another sample project in the not distant future which targets .Net Core. It also currently doesn’t make use of either a proper front end framework, or of most of the functionality that MVC5 exposes on the front end. I haven’t written this application to be overly robust, and due to the nature of how it consumes API keys without any authentication I wouldn’t expose it on a publicly facing web server.

Get the code

With all that being said, the code is available here: https://github.com/lbearl/BlockListChecker.

Part Two of the series is available here

PucciThe.Dog – Python/Flask on an RPI

Overview

Flask is an amazing little Python web micro-framework for those who aren’t familiar with it. It allowed me to build out this entire application in about 8 hours of total dev time (including a whole bunch of time just not quite grokking flask-login). The minimal goals I wanted to achieve was to expose a very basic web presence for Pucci (the dog), along with building a very basic puppy cam. Since I had an old Raspberry Pi lying around, I figured that this might be the ideal project to use it for.

Please feel free to take a look at the code

Bill of Materials

  1. Raspberry Pi
  2. Microsoft LifeCam NX-3000
  3. Sweetbox Case (optional)

The Plumbing

In the interest of making this work as quickly as possible, the actual picture-taking logic is just a shell script running in cron (specifically once every 5 minutes). It likewise will examine all of the files in the directory and delete any that are more than a day old. The real magic is actually done by fswebcam as documented here.

fswebcam -r 320x240 --jpeg 80 -D 3 -S 13 \ 
/home/pi/poochpics/$DATE.jpg

Technically the webcam should support higher resolution pictures, but I suspect that it isn’t quite as compatible as I was led to believe it was. The -D 3 -S 13 are very important for me as the camera was corrupting 70+% of the images that it was capturing. These arguments will first delay the capture for 3 seconds and then skip the first 13 frames captured, finally generating a photo based on the 14th frame captured. This numbers were very scientifically found by simply playing with the webcam until it was returning reliable results 100% of the time (it is possible that others will be able to operate the webcam without any delay or skipping any frames).

Now that all of the photo generation and automatic purging of old images is handled the actual responsibilities for the web application are pretty slim: basically just a regular old mostly static web page with the ability to login to a secure area which will have the actual photos on display.

I made the jump to almost 100% Windows at home (since I have been working on Windows machine for pretty much my entire career), and decided to use this project as an excuse to try out the Python Tools now available in Visual Studio (spoiler alert: they are awesome). I can’t say that I have ever really used an IDE for Python development before (traditionally I’ve done it in a mix of Vim and Sublime Text), so I can’t compare it to some of the other Python IDEs out there, but as someone who gets paid to do C# in Visual Studio 2015, the experience was very nice.

Implementing the Web Application

In order to actually get things working I just started with the default template that comes with VS for Flask + Jinja2 templating (I contemplated doing this project as an Angular app with a Flask RESTful backend, but decided against it). The code is pretty basic especially considering the entire application only consists of 4 routes and doesn’t really do any magic (there isn’t even a CRUD component to it). The one thing that isn’t exactly standard was my choice for authentication. As I mentioned earlier, this application does use flask-login, and while my original thought was to just hardcode the credentials, I ended up not going down that path as I couldn’t come up with a non-hacky way to persist the credentials that wasn’t less complex than just adding a SQLite database with some credentials tossed into it. To that end if you look at __init__.py you’ll notice the need to have a SQLite db called test.db. This database just has a single table called “user” which will store ids, usernames, emails, and bcrypt hashed passwords:

Deployment

It really is an exciting time to be alive when I can build something on a Core i7 desktop with 32 GB of RAM, and then relatively effortlessly deploy it onto a computer the size of a microcontroller with a whopping 512MB of RAM and a sub-1Ghz ARM processor. The deployment is actually pretty standard: it’s just Apache2 with mod_wsgi and the appropriate wiring as described here. The most interesting part of all this is probably the way that DNS is being handled: Namecheap now offers Dynamic DNS, so I have ddclient running on the Pi, automatically updating my home IP address to Namecheap’s DNS servers. If you want to try it out for yourself and give me a little boost in the wallet as well sign up here.

The only thing I’m a little nervous about with this setup is whether or not the relatively underpowered RPi really is going to do that well connected to the public internet. That being said, it is pretty heavily firewalled, with only port 80 exposed so its a fairly limited attack surface for any of those internet hooligans.

I hope you enjoyed reading about my very small flask application on a RPi, please reach out to me on Twitter @lukebearl or head over to Github.