To do: write “to do” app with ASP.Net Core
Zone’s head of .NET development, Andy Butland, has put “to do” applications at the top of his ASP.Net Core to do list…
It’s almost a parody now that whenever a developer wants to start investigating a new technology further than just a bit of reading, and they reach around for something to actually implement to learn some more, they come up with building a “to do” application. Maybe indicating a lack of imagination, I’ve not bucked that trend in my first hands-on investigations into ASP.Net Core.
As background, ASP.Net Core is a ground-up, open-source rewrite of ASP.Net — a web application framework now around 14 years old that has formed the basis of most of the website solutions Zone has built over this time. As a .Net developer, although every year has seen continuous improvements and development of the framework, I see it as the third wave of change that we’ll need to ride. Initially there was the move from the (now known as) “classic” ASP to ASP.Net. Following that we had the introduction of ASP.Net MVC, a new pattern for the framework for building better structured, web applications. And now we have the move to ASP.Net Core.
In implementing this very basic “to do” web application I wanted to try to continue to use some patterns of DDD (domain driven design) and CQRS (command query responsibility segregation) that we now regularly use in ASP.Net MVC web applications, and have blogged and spoken about elsewhere before. I’ll discuss in this article working with some of methods, noting what’s different and what’s still quite familiar when using ASP.Net Core and Entity Framework Core.
Rich domain model
It’s hard to describe a model as “rich” when it only has a couple of entities of course, but what I wanted to establish here was the use of a DDD style of model construction. Specifically this involves:
- Removing the empty constructor so only objects with valid setup can be created
- Removing the ability of calling code to arbitrarily set property values and instead call defined methods to update state
- Implement behaviour in the model in terms of methods on the entity classes
In my limited example this worked as expected and as it always did with .Net and Entity Framework (EF). The only concession is the need to create an empty constructor that EF requires. This can be marked as private though so doesn’t leak through to the calling code.
The two model entity classes then look like this:
And are associated with the EF context like this:
Models can be updated and migrations generated to update the database much has always been the case when taking a “code-first” approach with EF.
The idea behind implementing a CQRS pattern for the application is to provide separation for reads and writes. At scale this can be a powerful technique for obtaining optimum performance but even with smaller web applications I find it a useful pattern to use. It leads to the creation of a number of small, tightly focused classes, each responsible for defining or carrying out particular read or write operation. The reads extract data from the database via EF according to a provided query and populate a view model, whilst the writes take a command instruction message and execute the necessary updates to the database.
Where I’ve previously used this pattern I’ve leaned on a setup based on using the IoC container Ninject. Handlers for particular query and command operations are registered with it and instantiated when required as particular read and write operations are requested from the controller. It leads to a very clean codebase with focused, testable handler operations and thin controllers.
With ASP.Net Core though we have dependency injection (DI) built in and so it’s possible to use this, which I did so with the help of the Mediatr library written and maintained by Jimmy Bogard, which can be hooked up with the ASP.Net Core DI quite easily as he describes here.
I also make use of another library by the same author: Automapper. This takes away some of the otherwise laborious code that needs to be written to map domain models to view models — a separation I like to ensure. Again it can be hooked up with the DI container such that the mappings are initialised using a simple helper extension method, as described here.
So taking a read example, we have these classes for the view model, the query and the handler respectively:
And for a write operation, the command, a generic result type and the handler as follows:
It’s in initialising the application that most change is noticed. ASP.Net Core applications start with almost literally nothing — not even the serving of static files — so it’s necessary to opt-in to everything as you need it. The following shows an example of my StartUp.cs class, enabling static files, MVC, sessions and wiring up the EF context, the mappings and the read and write handlers:
Must of the MVC concepts and syntax carry over from previous versions. Whilst there’s been a full rewrite and integration of the previously superficially similar but actually quite separate MVC and Web API frameworks, there’s been a strong focus on backward compatibility here. Given that, controllers are implemented much as previously, with just a few, subtle differences such as the use of the IActionResult return type:
Within the views we still use Razor for rendering though one welcome change is the introduction of tag helpers. These replace the HTML helpers we have in previous versions of ASP.Net MVC, providing a syntax much closer to HTML and thus more easily worked with by front-end developers less familiar with C#.
For example, for a link to a controller action, we can replace this:
It’s in the views I ran into some minor problems due to the current status of the ASP.Net Core. Whilst the framework itself is now recently released to market, the tooling is still in preview and subject to change. Within Visual Studio, when opening the views I’d find a number of warnings and errors being flagged that weren’t actually issues, which was a little annoying to work with.
Way of working
Once nice benefit of the new framework is the “just in time” compilation, which means as a developer you can work in any part of your code — not just views as before but also in controllers and other C# classes — and refresh your browser to see the updates. The process of code → build → refresh is so ingrained in me though that I probably need to lose that bit of muscle memory before really seeing the benefits!
Tooling issues noted above notwithstanding, there’s a few productivity benefits I appreciated when working on the application. Whether it was coming from Visual Studio or Resharper I’m not 100% sure, but the prompts when using a class that wasn’t yet referenced indicating that it was available via NuGet through a single click to install was a very useful time-saver.
In summary, whilst this is a very basic application, it came together quite quickly and, other than in a few cases such as initialisation, was quite familiar as an ASP.Net MVC developer. The code for this sample application is up on GitHub here.