Note: This article applies to beta software and comes with no warranty or support, use at your own discretion. You must have Visual Studio.Net 2010 Beta 1 installed on your machine to make use of the code.
KandaAlpha now hosted on CodePlex, download from http://kandaalpha.codeplex.com/
This is an article which builds on a previous post on domain drive design architecture using asp.net web forms and Entity Framework v4.0. now, we leverage that core architecture to have a db40 object database as the back end and an asp.net mvc web application at the front end.
-
db40 is an object database which means there is no mapping files, attributes or other ‘impedance mismatch’ between your c# classes and the ‘database’ itself. It’s mostly used in embedded scenarios but appears to be getting used in websites. I’ve only just scratched the surface with it here, but i think it’s very cool and i hope it gains more and more traction.
-
asp.net mvc is the latest and greatest presentation architecture for asp.net and includes great separation of concerns between the various layers. In the architecture presented here, the Views and Controllers are within the asp.net mvc web application and the Model is essentially the domain model (e.g. KandaAlpha.Domain.Model)
My previous post discussed the architecture presented here solely within the context of the Entity Framework 4.0. It was also limited to usage of Web Forms on the front end. This release includes that working example but also includes into the solution an asp.net mvc 1.0 application which builds on the architecture and is backed by a db4op powered repository.
The first things i did were:
- Added an MVC application (KandaAlpha.UI.Mvc) which is the front end side of things, with controllers that dependency inject the services and repositories as before.
- Implement new repository for db4o (sorry, in the application i misspelt and used a zero, doh!) in KandaAlpha.Infrastructure.Repository.db40.
- Update the web.config of the mvc application (and associated tests project) to wire the Unity dependency injection so that the db4o repositories are returned for repository interface requests
Changes to Dependency Injection Approach – Service Location vs Constructor Injection
I released this post last night and then got some good feedback from Will Beattie about design smells around my choice of Service Locator pattern approach to the dependency injection within the mvc controllers. One other approach as discussed in this post’s comments is to use constructor injection dynamically on the controllers. So, you can see i’ve added a custom controller factory.
In addition, Will had commented ton the controller’s dependency on the repository layer. I wasn’t too fussed about this given repository is within the domain and simply consists of interfaces but i did break it out for completeness. Notice that this does mean you get duplicate interfaces on the service layer in many cases. In practice, i would be quite happy to expose repository through the service layer but made the change anyway for completeness.
It’s worth noting i do still make of the ServiceLocator pattern within the mvc controller factory itself and also within global.ascx.cs Application_End which is where i ‘clean up’ the Repository Context (e.g. kill to db40 database ‘connection’).
So in general, the trend seems to be to favour constructor injection but there will sill be scenarios where a service locator pattern can prove useful, particular when mocking/testing may not be required.
Unit Test Isolation
If you take a look at the unit test for the controller now you can see how easy it is to mock up the controller without recourse to any dependency injection. In fact, the test is failing because i haven’t gotten round to implement a SaveChanges() for the in simply memory repository i built.
Before the unit test was admittedly an integration test, and it appears cleaner now, although it would be more work to maintain an in memory repository for a larger more complex application, but more advanced mocking tools may help with that.
How the mvc project runs
When you run the mvc project, it simply displays 2 customers on the screen. I’ve also added a little update on one of the customers as you refresh the page, just to show how to save things back to the db40 file.
This all took less than 2 hours and i was very pleased to get things up and running so quickly. It hopefully shows you some of the power and flexibility of dependency injection and the domain drive approach as well as introduction you to how use such an architecture with technologies like asp.net mvc, db4o and entity framework.