Jonathan Worthington: Why I use ASP.NET MVC

Why I Use ASP.NET MVC
I used to do a lot of web development. These days I do rather less of it - I'm far
more involved with architecture and teaching - but most of the systems I'm
involved with have a web frontend, so I keep a very keen eye on the technologies
that are available. Additionally, I often end up building small tools that need
some kind of interface, and I'd much rather whip up a web one than mess with
desktop apps. Many development shops in Sweden work with .Net, and these days
often choose between Web Forms and MVC. I suspect the title of this post gives
you a good idea of my preference. :-)

Embracing the web
Good technologies often embrace the way the thing they're built on actually
works. Take jQuery. It doesn't try and fight JavaScript having prototype based
OO by fudging a class system on it, as various efforts to tame JavaScript did.
Instead, it embraces it - and the results are pretty nice.

ASP.NET Web Forms suffers from a certain amount of fudgery: it tries to hide the
stateless nature of the web by saving state for you. The result is view state
(which bulks up pages) and mangled field names (which make client side development
a little more painful). Trouble is, the stateless nature of the web matters; it's
an important part of why it has scaled so well.

ASP.NET MVC embraces the way the web works, and focuses on allowing you to work
efficiently within that. There's no view state. The HTML you write is the HTML
you get. IDs don't get mangled. ASP.NET Ajax is mostly dropped in favor of jQuery
(by now something of a de facto standard).

A better factoring
To be fair, Web Forms did bring huge advantages over classic ASP when it arrived.
It put an end to mixing up logic and HTML in a single file, separating them logic
out into a codebehind file. Unfortunatley, the factoring hasn't really stood the
test of time. These days, developers are more interested than ever in writing
tests, and dependency inversion often shows up with this desire. Web Forms isn't
too friendly to either of these goals.

MVC makes a three way division. HTML goes into the view, which is rendered by a
view engine. There are no controls like in Web Forms; there are, however, helpers
for generating various pieces of HTML. The data that the view is to render is
supplied in the model. The model is just some .Net object. There are no constraints
on what this object can be, so you can do anything from using entities from Entity
Framework (which usually is a bad idea, mind) to a command object being built up
in a CQRS based system.

The interesting logic lives in the controller. In ASP.NET MVC, a controller is a
class that inherits from the Controller base class, and contains methods that
are known as actions. Each time a request is made, it is routed to the applicable
action method. This method builds the model and selects the view - thus it is in
overall control of the request's processing.

Why is this more testable?
The controller is a normal class. You can make an instance of it in your test, call
the action methods (since they are just normal methods) and look at the return value,
which in turns lets you get at the model that the controller built. Essentially, it
is a lot like writing tests against any other class in .Net; you can use whatever test
tools you are familiar with.

And what of dependency inversion? The MVC framework provides a hook for you to integrate
a DI container of your choice, such as StructureMap. In fact, for some of them there are
even NuGet packages to do the wiring up for you.

What's coming up?
ASP.NET MVC is very actively developed and has frequent releases. Version 3 didn't come
out all that long ago, and yet version 4 is already in beta! Perhaps most exciting is
that it will bring Web API, a way to implement REST-based web services. It looks rather
more convenient than WCF for this kind of task, and the factoring will feel familiar to
anybody who is already used to working with ASP.NET MVC - it's just a different type of
controller!

Learning More
I teach a 2 day getting started with ASP.NET MVC 3 course for Informator. At the moment,
I'm working on updating it to cover ASP.NET MVC 4; it will also be extended to a three
day course to allow this, but also to enable me to go into much more depth on testing. Also,
we're planning the next Community Day, and I expect to be giving a talk on Web API.

/Jonathan Worthington

The use of events for decoupling business logic

Why I Use Events
Events are a relatively simple, but very powerful idea. At its simplest, an event is a statement that something has happened. Usually, it includes some data that further defines what has taken place. Events show up very naturally when doing GUI programming, either for the desktop (think WinForms) or web (JavaScript).

However, that's not the use case I want to discuss today. Instead, I want to consider the use of events for decoupling business logic.

Boundaries
Lack of boundaries has to be one of the most common problems I see in software systems. Layered architecture has taken a hold in many systems, and often helps bound the UI and business logic (and sometimes too many other things beyond that). However, too often the business domain is seen as one big thing, with no serious effort made to look for and maintain explicit boundaries. Both DDD and SOA are pretty clear that we need to hunt for such boundaries, however.

The argument that tends to crop up next is that one part of the system will often need to know what's going on in other parts. For example, it's very well for a travel company to say they'll bound sales, booking and their transport services into separate services or contexts. However, in reality, if a booking were to be cancelled at the last minute then the sales context should know about this so they can do a special last minute deal, and the transport services context also need to remove the passenger from its lists.

Clearly, the booking context is responsible for handling the cancellation. In a monolithic system, the cancellation logic would mark the booking as cancelled, and then go and handle the notification of the sales team and updating the passenger list. If we are series about boundaries, however, then this simply isn't going to fly. So what can we do?

Publish Subscribe
We can resolve this problem using a popular messaging pattern, known as publish subscribe. First, we define a BookingCancelled event. Typically, I would just represent this as a simple class.
public class BookingCancelledEvent{
public int BookingID;public List Passengers;}
The booking context would mark the booking as cancelled and do anything that is directly related to bookings. It would then publish this event. Meanwhile, the sales and transport contexts would be subscribed to booking cancellation events. They receive the event, look at the data contained within it and take action as appropriate.

We have now managed to achieve a very loose coupling between the different parts of our business system. The only things that flow over boundaries are events. Should a new context be interested in knowing about cancellations, then it's trivial to handle; the booking context needs no changes whatsoever, and the new context is just added as an extra subscriber.

It's all in the past
The naming of events is of great importance. An event should always be in the past tense. This makes it absolutely clear that the event in question has already taken place. There's nothing a receiver can do to change that it happened; they can only act upon that new reality.

Events should also have a single source. It should never be possible for more than one context to publish the same type of event. This maps down to a deeper principle: every piece of information in your system should have a single owner that is responsible for it. It's fine for other contexts to maintain their own local copies of the data, or at least the parts they are interested in – but there is only one single authority for it.

Implementation
There are many ways to implement events along with publish subscribe. For a small, single-process system then a relatively simple in-memory message bus or event aggregator isn't a great deal of code. For larger systems, however, events come in to their own. Using an enterprise service bus - such as NServiceBus - enables a service to publish events and other services to subscribe to them. Such systems use store and forward, providing reliable and asynchronous message delivery.

Learn more
I consider events important, and thus they show up in many courses I'm involved with. Of note, in the C# Masterclass I work through building a simple in-process event aggregator. The Software Architecture course talks about events somewhat. They will also be a core topic in the forthcoming Hands On DDD and CQRS course, where we'll consider events not only as a mechanism for decoupling, but also as a primary storage mechanism.


/Jonathan Worthington

Jonathan Worthington: Why I use Git

Git, if you haven't come accross it yet, is a version control system. Developed
by Linus Torvalds, creator of Linux, Git has taken the version control system by
storm in recent years - and with good reason. Distributed, with outstanding branch
and merge capabilities and just plain fast, Git enables developers who master
it to work more productively.

But wait a minute, what's version control all about?
As a system is developed and maintained, various changes occur. These changes may
add new features, fix bugs, refactor code, improve documentation and so forth.
Version control is about keeping track of these changes. It ensures that multiple
developers don't accidentally stomp on each other's changes. It enables you to do
bugfix releases of a product without having to ship the latest development work.

Centralized vs. Decentralized
Traditionally, version control systems have been very centralized. A central server
keeps track of all of the changes. Developers run version control client software on
their machines, which they use to get a copy of the current version of the code, fetch latest updates, review the changes they have done locally and then commit them to the central server. Questions about historical versions are answered by the server, which has a full view of the version history. This is the model followed by systems such as Subversion and TFS.

Decentralized version control systems are different. Every developer gets a full copy
of the version history on their local machine. This means that looking back in time is practically instant. You may think that this must be extremely costly in terms of disk usage, but in reality this doesn't tend to be the case; Git is extremely efficient when it comes to storing history, and in some cases fetching the entire histroy with Git can be faster than getting a single version with Subversion!

It goes much, much further than just viewing history locally, however. All operations
are available locally. You can commit to your local copy, create and merge branches in your local copy - in fact, you can work version controlled without any access to the central server, and synchronize your changes when you are ready. No more development grinding to a halt because the central server broke down! And since you are working locally, you have the power to get your commits in order before sharing them. Silly mistakes can be fixed without anybody knowing you made them, making for a cleaner version history - and the illusion that you're awesome.

Won't this be chaos?
At this point, you may have realized that it is possible to build up a set of
commits locally, and other developers can do the same. Essentially, it's like
everyone is working in a branch all the time, and merging to a central location
in order to share commits. So won't life become full of painful merges?

If Git changed anything for me, it was my view of branches and merging. Before
Git, a branch was a big deal. It wasn't so much that making the branch was an
issue - although in Subversion that meant making an entire copy of the source
tree, which was hardly fast. It was the merging that made branches a nuisance.

Happily, Git makes branch creation virtually instant, and creates them in place -
which means you can switch branch without having to change directory. Most
important, however, is that it works really hard for you when it comes to merges.
Thanks to the way it tracks history, and by employing multiple merge algorithms,
Git is able to take care of most things automatically, leaving you to resolve the
things that tend to genuinely need a human decision. By way of example, I recently
merged a branch that had diverged from the mainline by 200 commits, with changes
touching 80 files, and I had to resolve 3 issues by hand. This relatively large
merge was all over in well under five minutes.

So what's the catch?
Honestly, Git has a learning curve. Some people refer to it as an "unlearning
curve" - you have to learn to forget what you thought you knew about version
control. While that's a cute perspective, it doesn't change the fact that
getting started with Git needs you to invest a little time understanding the
underlying model and how to get stuff done with it. It's not so much that it
is inherently difficult - but it is different, and that takes time to get used
to.

My first few days using Git were confusing, but I was lucky enough to have lots
of people I could ask for hints when I got stuck. It wasn't long before I was
comfortable, and not all that long afterwards when I was answering questions
from others who were starting their Git journey. By now, I use Git just about
every day, for work projects, open source projects and personal projects. I
appreciate the speed, the way I can effortlessly branch and merge - which
has changed the way I work for the better - and many little bonus features
that make my day to day development that little bit more efficient. By now,
the time I invested in learning Git must have paid itself back many times
over, and will continue to do so for many projects to come.

Interested?
Myself and my other Git-fond teaching colleagues have put together an
introduction to Git, in hope that we can share what we've learned and help
others to enjoy the same productivity boost. See more at:

http://www.informator.se/utbildningar/metoder-och-modeller/arkitektur/introduction-to-git.aspx

/Jonathan

Ny kurs! Hands-On DDD and CQRS (with .Net or Java)