It occurred to me a while ago it would be a good idea to have a dig through some open source code. Why? Primarily because in the last few years I've spent the majority of my time working on two codebases, one at home and the other at work. I feel very much in my own little code bubble. Working with the same code day in day out you become familiar with the conventions and patterns chosen and you can get into a rut.
So, the point of this exercise is to get me out of my comfort zone and learn something new. How have other people solved problems I've faced? What is their code like? How to they handle errors? What new ideas or ways of working can I apply to my code?
Suteki Shop
Suteki Shop, written by Mike Hadlow using NHibernate and .NET MVC, is an open source eCommerce site aimed at the fashion and retail industry. I figured it was a good place to start because looking through an unfamiliar codebase is difficult but.NET MVC is my day job so that will give me a head start.
Observations
- The UnitOfWorkAttribute is a great way of encapsulating all database operations in a single action into a transaction and committing on success or rolling back on exception
- Exception handling is minimal. It seems to only be added where it's really required resulting in really clean code
- Really nice use of fluent interfaces to create more readable code when mapping data to view models
- Generic repositories make CRUD operations ridiculously simple
- On the whole the controllers are short. Unnecessary code hasn't leaked into them which I find often happens in my work codebase
- Some domain objects fire events whose handlers call methods on services classes, which is a mechanism I've never considered using. E.g. The Order object has no dependencies on any other class, but if you call Confirm() it will set OrderStatus to OrderStatus.Created and fire an OrderConfirmed event whose handler calls EmailService.SendOrderConfirmation. It's a nice way of running non critical tasks
- Object values can be retrieved from the database as if by magic using the power of the EntityModelBinder
ScaffoldController<T>
This is really interesting. It's CRUD done right. Several controllers inherit from this and they contain a couple of attributes and no other code.
Repository operations are possible because the generic class that applies to the controller also applies to the repository. That generic class is also used to build the view which can store a single item, list of items or return data for a drop down list.
Obviously there are down sides to this approach. It can't be used if you want to do any non standard operations and you still need to create the view.
What can I take from this?
- Chaining methods with fluent interfaces is great for creating readable code, I don't use it enough
- There's really no reason to put any kind of logic in the controller, it can always go elsewhere
- I don't understand generics quite as well as I'd like
- Model binding is something I should read up on
- Not all actions in a web application need to be done synchronously. If something isn't critical it can be carried out using events or some other async process