This post is to announce the release of Blunt Architecture, a lightweight web application framework built on the ASP.NET MVC framework. My hope is that the Blunt Architecture project will help developers new to ASP.NET MVC get their feet wet by providing them a solid foundation to build upon. I know that for me, having a lightweight sample project to play with always speeds up the learning curve. As always, your comments are welcome, so please let me know what you think.
To start playing with the bits immediately, the source code is available here, or you can checkout the latest version using Subversion at http://bluntarchitecture.googlecode.com/svn/trunk/
To learn more about Blunt Architecture, read on. The following is taken from the project documentation:
The Blunt Architecture project is a lightweight web application framework showcasing ALT.NET best practices such as:
- Domain driven design
- Test driven development
- Inversion of control / dependency injection
- Model, view, controller
The Blunt Architecture project is based off of the S#arp Architecture project. Where the Blunt Architecture project differs is that it is meant to be used as a learning tool rather than a ready-for-production framework. Because of this, the Blunt Architecture project strives to avoid outside dependencies wherever possible. This allows the user to focus his or her attention on the concepts presented without the added distraction of also having to figure out the syntax and details of third party tools. Although this constraint causes certain tasks to be more tedious (e.g. object relational mapping, dependency injection, etc.), it should make the project more approachable to users unfamiliar with the third party libraries commonly used for simplifying the implementation of these concepts (e.g. NHibernate, StructureMap, etc.).
The overall goal of the Blunt Architecture project is to present ALT.NET best practices in the easiest manner possible while allowing the user the flexibility to plug in whatever third party libraries they wish once they are comfortable with the framework.
The Blunt Architecture solution is divided into five projects which will be detailed below. The web application contains only two pages: a home page:
And a customer listing page:
As stated above, this is a very bare bones project so please forgive me for the lack of a nice style sheet and pretty UI.
This project contains the controllers used by the ASP.NET MVC framework to handle and respond to user input. Specifically, it dictates what happens whenever a URL is accessed. For example, in the HomeController class, the Index function below determines what happens when the user accesses the URL http://localhost/BluntArchitecture/Home:
This is a pretty boring function. It just sets the Title key in the ViewData dictionary which will be used by the master page to specify the title of the page, then returns the View (which will be the Index.aspx page found in the Home folder in BluntArchitecture.Web). This is all taken care for us by the ASP.NET MVC framework which you can read more about here.
The CustomerController class is a little more interesting:
You will notice here that CustomerController also has an Index function, but that it passes along an IList object to the view. This object will be used by the view to display customer information.
You will also notice that the customer controller has a private variable of type ICustomerDao, which is an interface defined in BluntArchitecture.Core that contains all the data access retrieval functions we need regarding customer information. This variable is meant to be set in the constructor of the CustomerController class, so it can be easily replaced by our unit test code (this is referred to as dependency injection). Normally, this injection would take place via a dependency injection tool such as StructureMap or Spring.NET, but in order to simplify the project we are defining a default constructor which will set the ICustomerDao object to an instance of CustomerDao, defined in BluntArchitecture.Data.
This is where we define our business objects as well as our data interfaces. Currently, the only business object is a simple Customer class:
As mentioned above, the data interfaces are also defined here. The reason we define the data interfaces here and not in BluntArchitecture.Data is to promote a separation of concerns between BluntArchitecture.Core and BluntArchitecture.Data. Because we specify the interfaces here, BluntArchitecture.Core doesn't need to depend on BluntArchitecture.Data. This has several benefits:
- Developers are unable to sneak in data access code into the domain layer
- The domain layer remains completely ignorant to how the data layer does its job. It only cares that the data layer implements the interfaces it needs. This allows us to switch out data layer implementation easily).
- It allows us to use dependency injection to mock data access when testing the domain layer. This keeps our unit tests fast and dependable.
Here is our only data interface, the ICustomerDao interface which requires only one function to be implemented, GetAllCustomers:
This is where we define our data access layer. Currently, the only class defined here, CustomerDao, simply provides hardcoded results to the caller:
In a real application, this would be replaced with calls to a database or some other data store. How this is done is up to you (e.g. strong typed data sets, object relational mappers, etc.), just so long as you implement the interface. I specifically removed any decisions about data storage here to keep the solution as flexible as possible and to remove any third party specific requirements from the code (e.g. session management with NHibernate).
This is where the unit tests go. Currently, the only unit test in place is the CustomerControllerTest. This unit test just makes sure that the Customer page can be loaded up and that it loads up the correct information from the ICustomerDao implementation. You will find a MockCustomerDao class that demonstrates how dependency injection can be used to create dependable unit tests.
This is where the front end of the application is defined. I won't go into how things work here as information regarding that can be found on [http://www.asp.net/mvc/ the official Microsoft ASP.NET MVC page].
If there is enough interest in the project, I'd like to expand on this code base to show how to plug in third party libraries to speed up development (e.g. NHibernate, LINQ to SQL, Subsonic, StructureMap, Spring.NET, etc.). Other than that I'm not sure I would want to add to the project as the motivation behind it was to keep it simple enough to function as an introductory sample. If you have any thoughts, I'd be more than happy to hear them.