[This particular post is intended for people who are at least a little familiar with S#arp Architecture and explains the motivations for S#arp Lite. For a comprehensive 101 on S#arp Lite, read the next post. To get right to the code, visit the S#arp Lite GitHub repository, download SharpLite_0.42.zip and follow README.txt.]
In April of 2008, I announced a project I had been working on called S#arp Architecture. This framework, for developing scalable, ASP.NET MVC applications with NHibernate, strove to adhere to the following key principles:
- Facilitate Domain Driven Design in project development
- Enforce Loose Coupling in project structure
- Preconfigure infrastructure (to take care of all the tedious plumbing)
- Support open-ended presentation
I've been pleased to have seen S#arp Architecture downloaded thousands of times and used on many many real world projects. (I can count at least a dozen cradle-to-grave S#arp projects under my own belt.) It has also had some terrific leaders and contributors along the way, including Alec Whittington, Seif Attar, Lee Carter, Jon George, Simone Busoli, Luis Abreu, James Gregory, Martin Hornagold, Jay Oliver, Frank Laub, Geoffrey Smith, Dan Smith, Kyle Baley, Chris Richards, and Howard van Rooijen.
Over the years, I've reflected upon what could be done to make S#arp easier to understand, more tenable for a larger audience, simpler to develop with...all the while, keeping it scalable for larger projects. S#arp Lite reflects this effort...
S#arp Architecture with a Lapband
To create S#arp Lite, I started with S#arp Architecture, grabbed a machete, and went to town to whittle the code down to the absolute essentials. After the dust settled, here's what was left of the S#arp libraries:
- ASP.NET MVC 3 with Razor as the underlying framework and initial presentation layer (can be swapped out for ASPX);
- A base domain object for providing "domain signature," comparison capabilities;
- A minimal, base repository including Get, GetAll (returning IQueryable), SaveOrUpdate, and Delete;
- Inclusion of NHibernate ORM suppor for convention-based, data mapping; and
- An MVC model binder for binding entity associations to an object from a form.
That's about it. What about Fluent NHibernate you ask? Gone. NHibernate Validator? Gone. MvcContrib and SQLLite? Both gone. AutoMapper, Newtonsoft.Json, WCF, Caliburn.Micro, MEF, PostSharp, RavenDB, Specifications? All gone. Although all of those features are handy, I felt that all the extras began to stand in the way of understanding the core principles of S#arp and should be included at the project level (not in the reusable S#arp Lite libraries).
The Disappearing Repository
One of the biggest pain points that my S#arp Architecture projects (and other teams' projects) have experienced over the years is the explosion of repository interfaces, repositories and "pass through" service classes which do nothing but re-route a request from a controller to a repository method. Because the queries were NHibernate-dependent, the repositories wrapped the NHibernate-gory details in concrete repositories, only exposing their querying capabilities via interfaces. Accordingly, you'd end up with hundreds of repository interfaces on large projects, all in the name of hiding NHibernate from the other layers. Although previously necessary, the game has changed.
With the mature, LINQ provider that NHibernate provides, there is no longer a need to wrap queries within repositories. The LINQ queries, run against the repository's GetAll() method, can now be added directly to application-service/task-layer classes or as stand-alone query objects in the domain layer. They don't necessitate a reference to NHibernate and so your layers still remain cleanly separated while being able to do away with all those annoying repository classes.
Adherence to the Original Architecture
One of the primary goals of this effort was to simplify S#arp while remaining in strict adherence with the original architecture. Let's take a step back to see how the architecture looks on a S#arp Lite project.
This is very similar to the overall architecture of S#arp Architecture. The biggest changes in S#arp Lite, with respect to the architectural approach, are as follows:
- Controllers have been moved into the .Web project to better reflect their role as part of the presentation layer. (I believe this may have been done in the most recent S#arp as well.)
- An .Init project has been introduced to remove extraneous dependencies from .Web. (Although .Init is very small in size, it helps to eliminate many initialization related dependencies from .Web.)
- Since there are no more custom repositories, the data-access layer, .NHibernateProvider is very thin and only has the bare essentials for initializing NHibernate. In fact, its role is so reduced, that it could be swapped out with an .EntityFrameworkProvider (more on this below).
If you've used S#arp Architecture before, you'll quickly notice that the overall architecture is almost identical to before...this is very intentional. The architecture has and always will be a pivotal aspect of keeping the layers cleanly separated. The original, architectural layout of S#arp Architecture worked well and has been preserved, for the most part, in S#arp Lite. (S#arp Lite has just been severely trimmed down to the bare essentials.)
Who is S#arp Lite intended for?
S#arp Lite should be usable to a much wider audience. In fact, because of the switch from custom repositories to using LINQ against IQueryable, you hardly even need to know NHibernate. I hate to imply a one-size-fits-all architecture, but S#arp Lite can be used effectively on small projects (mom & pop stores) up to very large "enterprise" applications (e.g., an application which integrates with half a dozen other systems).
Is S#arp Lite backward compatible with S#arp Architecture?
Hypothetically yes, but it would likely be cost and time prohibitive to migrate a S#arp Architecture project to S#arp Lite. With that said, on our existing S#arp Architecture projects, we've added an IQueryable method to our base repository to help with getting rid of new repositories.
Is S#arp Lite going to change very much over the next year?
Absolutely not. It is going to remain almost exactly as is; with only upgrades to internal components when necessary (NHibernate, ASP.NET MVC, etc.). It is very much intended for S#arp Lite to hardly grow at all for the foreseeable future to avoid any bloat. Sure, contrib projects are welcome, but S#arp Lite will not be growing in size. The only anticipated growth of the project is the inclusion of CRUD scaffolding.
What about S#arp Architecture?
S#arp Architecture is still alive and well under Alec Whittington's guiding light; it's primary advantage now and forever more will be its wide array of options and solutions for various scenarios, such as WCF, SQLLite unit testing, PostSharp, etc. These options simply aren't built into S#arp Lite and won't be...if you use S#arp Lite, it is expected that you'll extend it as necessary to meet the specific needs of your project.
Didn't you say something about .EntityFrameworkProvider?
Because S#arp Lite greatly de-emphasizes the need for custom repositories, NHibernate almost becomes a minor infrastructural concern, something akin to log4net. Well, perhaps not that minor of a role, but certainly closer than before. Because of this, S#arp Lite projects are very lightly coupled to NHibernate....so much so that I feel the SharpLite.NHibernateProvider layer could be (easily?) interchanged with a SharpLite.EntityFrameworkProvider using Entity Framework 4.1. I've put the beginnings of such a layer into the S#arp Lite solution; unfortunately, I'm not versed enough with Entity Framework to know the best way to develop this layer, nor how to properly use it to effectively replace MyStore.NHibernateProvider in the MyStore sample project. If anyone is up for an interesting challenge, I would be interested to see if SharpLite.EntityFrameworkProvider could be built out and used as the data-access infrastructure for the MyStore sample project.
I'm bored with all this chatter...what next?
Alright, let's get to the fun stuff. For starters, the S#arp Lite source (and pretty good sample app) is available at https://github.com/codai/Sharp-Lite. Let's create a S#arp Lite project so you can see what it's all about...
Check out the Sample Project & Create your first S#arp Lite project
- Download SharpLite_0.42.zip from the downloads tab of https://github.com/codai/Sharp-Lite
- Follow the instructions in README.txt
Subsequent posts will go into more detail about S#arp Lite (for a 101 overview) and will begin providing a cookbook for developing your own S#arp Lite projects. (If you're at all interested in helping with the addition of some ASP.NET MVC scaffolding with MvcScaffolding, you're most welcome to contribute!) I look forward to hearing any and all feedback, for better or worse.
10-26-2011 4:59 PM