Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Billy McCafferty



S#arp Architecture: ASP.NET MVC with NHibernate

To skip to the chase...  http://code.google.com/p/sharp-architecture/

It wasn't too many years ago that I used to state quietly that I was a Microsoft web developer.  Inevitably, a Java developer would hear my whisper and begin laughing hysterically as I cowered away from defending Active Server Pages.  Not long after, I felt a bit more confident defending Microsoft web development after the introduction of ASP.NET but have yet to this day been able to accurately describe the page life cycle or defend why the *%$@ it was ever a good idea.  While the .NET language continued to progress into a world class language with generics and LINQ, I often wondered when the presentation layer would get the attention it deserved.  To add insult to injury, the Rails crew was quick to join in the hysterics that the Java community had long been enjoying.  To make up for the deficiencies of developing Microsoft web applications, many of us would come up with near ridiculous schemes to facilitate even a partial amount of test driven development and properly tiered layers.  With ASP.NET MVC, we now easily stand shoulder to shoulder with the clean separation of concerns enjoyed by other technologies.  But with any new technology, there is a dire and immediate need for communications and guidance concerning how to develop a solid, testable web application using time tested patterns for rapid development and long term maintainability.  With this post, I hope to do just for ASP.NET MVC.

Pronounced "Sharp Architecture," this is a solid architectural foundation for rapidly building maintainable web applications leveraging the ASP.NET MVC framework with NHibernate 1.2 and Spring.NET 1.1.1.  The primary advantage to be sought in using any architectural framework is to decrease the code one has to write while increasing the quality of the end product.  A framework should enable developers to spend little time on infrastructure details while allowing them to focus their attentions on the domain and user experience.  Accordingly, S#arp Architecture adheres to the following key principles:

Focused on Domain Driven Design

This architecture places emphasis on the domain as being the core element of focus.  Accordingly, the domain layer has no direct dependencies on any data loading mechanisms or other resource dependent services.  This facilitates a test driven approach to developing the domain without the need for external resources, such as a database, to be available during domain development.  (Alternatively, some developers prefer a model driven approach to application development.  A solid framework for supporting this alternative style is the ADO.NET Entity Framework.)

Loosely Coupled

All layers within S#arp Architecture depend only on the core domain layer and framework utilities.  In many applications, the presentation tier depends on a service tier which depends on a domain tier which depends on a data access tier.  A frequent problem with this is that every layer "up the chain" inherently depends on every tier below it.  This tight coupling makes it increasingly more difficult, as development on a project proceeds, to make modifications to lower tiers without having an adverse affect on the tiers above it.  Alternatively, this architecture keeps the tiers loosely coupled from each other; e.g., the controller and domain logic layers have no direct dependency on the data tier.  To facilitate this, the core domin layer, in addition to defining the domain model and logic, also define service interfaces which are needed by other layers.  (Examples of a "service" include a data access object, a ftp utility, or a web service.)  In this way, the controller logic only has knowledge of data access interfaces, for which implementation details can be injected at runtime.  This loosely coupled design further faciliates test driven development and allows dependencies to be more easily modified, if not completely replaced, with no affect on "higher" tiers.

Preconfigured Infrastructure

Developers often spend much of their time maintaining data access and other infrastructure related layers.  Furthermore, infrastructure to facilitate test driven development which bypasses live data access code is often complicated and error prone to configure.  By leveraging NHibernate 1.2 for data access, along with the benefits of .NET generics, it is rarely the case, using this described approach, that even a single line of code need be written to have full data access capabilities for a given domain object.  Spring.NET 1.1 is then leveraged to provide dependency injection of concreate data access objects into the controllers layer.  (Alternatively, the data access objects could be injected into a service layer when appropriate.)  To reduce the risk of introducing bugs into XML configuration files, this framework includes a Spring.NET XML configuration generator to handle defining data access objects (DAOs), controllers, and DAO injection into controller constructors.  The only time it is necessary to configure Spring.NET XML is when custom DAOs are required.  Note that this is the only code generation in the entire framework.  There is no bazillion lines of data access code generated upon every compilation.  There are no magically created partial classes to facilitate data access.  This makes for a much more understandable and maintainable application.

Open Ended Presentation

There are a plethora of great alternatives available for building the presentation layer of an application.  Consequently, S#arp Architecture mandates few, if any, constraints on how the presentation layer should be designed and developed.  In fact, the only constraint is that ASP.NET MVC be leveraged; other than that, any presentation option is available for use.  To illustrate, this framework shows no preferences towards any particular presentation solution such as jQuery, Yahoo UI widgets, or the Microsoft AJAX utilities.  As long as your preferred mechanism works with MVC, this framework will accommodate it.

To better facilitate community involvement, to provide releases for later versions of ASP.NET MVC and other framework dependencies, and to manage documentation (with a comprehensive walk through lab), S#arp Architecture is being managed at http://code.google.com/p/sharp-architecture/.  The corresponding discussion group may be found at http://groups.google.com/group/sharp-architecture.

I sincerely hope that this architecture will serve as a key element in enabling you to create high quality applications which both you and your clients can take pride in.  This work reflects the knowledge of industry experts, the feedback garnered from past experiences, and the help of many people who have lent a hand or provided guidance and/or feedback when needed.  Particularly, I'd like to thank Damon Carr, Ben Scheirman, Alan Northam, Mark Pollack and Erich Eichinger of the Spring.NET team, Wayde Gilliam and the hundreds of developers who helped me hone my ideas by providing great feedback over the past couple of years.  A special thanks also goes to Roy Bradley who made it possible for me to spend as much time as I did on this effort.

Some useful essential background material for this architecture may be found at http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx.  Although there are major changes in the infrastructure of the new architecture, the overall structure is similar to that presented in this previous article.  So it's a great starting point for getting up to speed with the knowledge areas included.

The overall goal of this architecture is to allow developers to worry less about application "plumbing" and to spend most of their time on adding value for the client by focusing on the business logic and developing a rich user experience.  Enjoy and keep the feedback coming!

Billy McCafferty



Comments

Martin said:

Great job!

# May 16, 2008 7:36 AM

Billy McCafferty said:

@Michael,

The decision of which IoC container to use was a difficult decision and one not easy to make; especially considering that I've been using Castle MonoRail, Windsor, (and ActiveRecord on a couple of small projects) for the past two years.  When it came down to it, my decision focused on Spring's very strong AOP capabilities, community involvement, available documentation (for supporting others), and subjective "fit" with ASP.NET considering its other utilities.  I still believe that Castle is an incredible suite of tools and deserves much of the credit for the MVC framework that Microsoft is now touting.  In fact, I'd go as far to say that MonoRail is much more developed and better MVC framework than ASP.NET MVC.  But with the "mainstream" introduction that ASP.NET MVC has received and the fact that Microsoft is being very attentive to the development community with respect to the direction it is going (can't say that for many MS things ;), I am anticipating that ASP.NET MVC will soon become the tool of choice for developing Microsoft web applications and that Spring is a suitable fit.

# May 16, 2008 9:04 AM

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# May 16, 2008 9:05 AM

{ null != Steve } » Sharp Architecture said:

Pingback from  { null != Steve } » Sharp Architecture

# May 17, 2008 10:24 AM

Wöchentliche Rundablage: Silverlight 2, ASP.NET MVC, C# 3.0, .NET 3.5 SP1… | Code-Inside Blog said:

Pingback from  Wöchentliche Rundablage: Silverlight 2, ASP.NET MVC, C# 3.0, .NET 3.5 SP1… | Code-Inside Blog

# May 19, 2008 3:41 PM

Weekly Links: Silverlight 2, ASP.NET MVC, C# 3.0, .NET 3.5 SP1… | Code-Inside Blog International said:

Pingback from  Weekly Links: Silverlight 2, ASP.NET MVC, C# 3.0, .NET 3.5 SP1… | Code-Inside Blog International

# May 19, 2008 3:43 PM

Luis Abreu said:

Hello Billy.

Great work! One thing that I've bee trying to understand is why you're fprcing the getdomaingobjectsignature to be a string. Are you doing this only to garantee proper implementation of the equals and gethashcode methods?

btw, I belive we're still waiting for a similar guide for WCF :)

thanks and keep up the good work.

# May 20, 2008 5:52 PM

Billy McCafferty said:

Great question Luis and one worth discussing further.  Although I don't feel it's a kludge, I don't have very strong reasons for why it's a string other than the convenience for supporting equals and gethashcode.  Do you have any recommendations for an alternative approach?

Thanks!

# May 20, 2008 6:34 PM

Luis Abreu said:

Well, not sure...I've been trying several approaches on the projects that I was able to squeeze NH in (yes, there are still lots of people that really don't  like ORM). I hadn't considered yours since I've been using the ID + classType name for implementing.

Anyway, I'll try using this approach because after giving it a second thought, it really looks like it will work better than the others I've tried.

Anywy, there's one thing that bothers me and that might be because I really don't have that much experience with NH. I'm seeing that you're delegating the delete to Spring,NET.

Ok, i might be wrong, so please correct me if that is the case. when you call delete, you'll get a detached object, right? shouldn't in that case the object have its ID set to the default value? Does NH do that automatically for you? If it doesn't, then shouldn't we do it? Or is it ok to have a detached object with an ID different than the default ID value?

thanks.

# May 21, 2008 4:41 AM

Billy McCafferty said:

Hi Luis,

To help clarify, the delete doesn't get delegated to Spring.NET.  Spring.NET's responsibilities are limited to injecting data access objects into the controllers.  Accordingly, to delete an object, two lines of code are necessary:  the first to load (or get) an object, and the second one to delete it.  E.g.:

Customer customerToDelete = customerDao.Load(1);

customerDao.Delete(customerToDelete);

Please let me know if this does not answer your question.

# May 21, 2008 7:58 AM

Luis Abreu said:

Hello Billy.

well, I thought that I didn't explain myself correctly when I wrote my last comment. Let me try again. It's not really the delete that I'm worried about.

What I was trying to say was: shouldn't the repository's delete method change the id and version  of the object being deleted to its default values after calling session.delete?

I mean, I see the repository's delete as making a persistent (maybe detached) object transient again and that's why I thought that its id should be set to the default value that is assigned to all the transient objects (if you don't do that - ie, change the id back to the default - won't you end up with a detached object instead of a transient object? ok, i know that the record is deleted from the db when you commit the transaction, but what I'm trying to understand is how will NH look at that object if you pass it again to, say, session.SaveOrUpdate method)

# May 21, 2008 6:42 PM

Billy McCafferty said:

Luis,

I believe the following is true.  If you delete an object but have not yet committed the transaction, then the object is transient but still "attachable" by invoking SaveOrUpdate.  So calling SaveOrUpdate would simply negate the delete.  (I'm not positive on this.)  But assume you commit the delete and then call SaveOrUpdate.  Since it sees that the object has an ID > 0 but no record in the DB to save it to, I'm almost sure it will throw an exception.  But again, I'm not positive on the above and a couple of tests would certainly be warranted.

# May 21, 2008 11:08 PM

Luis Abreu said:

yep, a couple of tests should do it. I'll try to run some, but I'm not sure when that will be...thanks again.

# May 22, 2008 5:32 PM

Brent Schooley said:

If nothing else, the name is weird.  How would one pronounce this?  ess-sharp-arp?  lol

# May 27, 2008 4:56 PM

Billy McCafferty said:

You're saying it wrong...it's a flat sharp.  ;)

# May 27, 2008 5:20 PM

Glyn Darkin said:

Hi Bill, Excellent work. I have been working on a project for the last 6 months where I had build all the back end in Spring and and now using MVC and JQuery for the front end. One thing I have done is create SpringPageView classes and SpringUserControlView class that inherit of the standard views but expose a IApplicationContext as a property to that I can use the Spring Resources for handling content strings.

Are you opening the project for other contributors, as I would love to help.

Cheers

Glyn

# May 28, 2008 5:28 PM

Billy McCafferty said:

Hi Glyn,

Thanks for the feedback.  I'll be moving the source code repository in the coming days to involve additional developers.  Thanks for the interest!

# May 28, 2008 5:34 PM

Hiew said:

When I tested it, the unit tests all failed because the expected assemblies for NUnit and RhinoMocks  was different from the ones included.

I had to replace the nunit.framework to version 2.4.1 (the one Spring was expecting) and the RhinoMocks to version 3.3. Then, the tests worked.

# May 29, 2008 2:07 AM

Hiew said:

One other newbie question

XML parsing exception is thrown on the Data.xml file stating that the database:provider element is not declared.

Why does this occur?

I tried changing around the connectionString to no effect.

By the way, I am using SQL Server 2005 so I retained the provider value as SqlServer-2.0

# May 29, 2008 2:24 AM

Billy McCafferty said:

Hi Hiew,

I'll be sure to add assembly redirects to the config files.  With respect to the database:provider element, did you replace the version of Spring.NET or change anything else whatsoever besides the connection string?

# May 29, 2008 8:50 AM

Hiew said:

The version of the Spring.NET assemblies within the Northwind.Tests bin/debug folder is 1.1.2

The db:provider element I am using is

<db:provider id="NorthwindDbProvider"

              provider="SqlServer-2.0"

              connectionString="Integrated Security=false;Data Source=(local);Initial Catalog=Northwind;User Id=test;Password=123456789;">

# May 29, 2008 11:56 PM

Billy McCafferty said:

The current code was developed using Spring.NET 1.1.1.  You may want to use what was provided in the original codebase.  I'll be upgrading to 1.1.2 soon.

# May 30, 2008 5:55 AM

Hiew said:

Thanks for the feedback.

Installed Spring.NET 1.1.1 on my PC instead of 1.1.2 and it went ok.

Thanks for the code base. Am currently using it to do some hands-on learning with nHibernate.

# June 2, 2008 6:45 AM

Adam Cooper said:

Hi Billy,

Let me begin by thanking you for your hard work in sharing your wisdom and experience with the rest of us. Your previous articles on CodeProject have been invaluable to me. You've helped me--a lowly, beginning architect working for a small company without any development peers to lead the way--understand how to bring together a lot of different technologies and methodologies. Your new ASP.NET MVC-based approach looks fantastic.

I realize ASP.NET MVC is in a bit of flux until its released, but do you have any plans to move the S#arpArchitecture framework to the recently-released ASP.NET MVC Preview 3?

Thanks again,

Adam

# June 4, 2008 5:29 PM

Billy McCafferty said:

Adam,

I'd like to move to MVC P3 ASAP.  I'm hoping to take a stab at this this coming weekend.  I'll certainly update this blog, accordingly.

# June 4, 2008 5:35 PM

Ryan Montgomery said:

Wow! When I found this my head exploded! My team has been working with Spring.NET/NHibernate/MVC on a project and to find a project like this is awesome! You mentioned updating to a more recent version of Spring.NET, is there any thoughts on upgrading to use the latest version of NHibernate? The Spring.NET team recently (very recently) updated the code base to work with the latest NHibernate version (2.0 Alpha). We've been using it mostly to take advantage of the new <join> ability in NHibernate, which has made working with some of our legacy data much less painful.

# June 4, 2008 11:22 PM

Nick said:

I seem to be having the same issue that Hiew did with the Data.xml file. The error is System.Xml.XmlException : The 'www.springframework.net/database:provider' element is not declared. Line 13, position 4. The assemblies are all 1.1.1. Any thoughts?

# June 9, 2008 12:58 AM

Andrew Scott said:

Hi :)

I was just wondering if you are upgrading this to MVC Release 3 and when you think it will be ready ? I'd love to start using/contributing to this project but I think I'll start once release 3 version is ready?

Cheers,

Andy

# June 9, 2008 10:08 PM

Billy McCafferty said:

Woohoo...upgraded!

# June 10, 2008 10:12 AM

Billy McCafferty said:

[Update 6/11/08 - To see an example of this in action, read the introduction of S#arp Architecture .

# June 11, 2008 8:07 AM

Lchd said:

Awesome!!!

Thanks a lot~~~

# June 12, 2008 1:40 AM

Mark Pawelek said:

Thanks for this Bill.

The link to www.codeplex.com/SharpArchitecture is broke. The gremlins have appended a dastardly space there: www.codeplex.com/SharpArchitecture%20

# June 12, 2008 5:31 AM

Billy McCafferty said:

@Ryan,

I will likely upgrade to NHibernate 2.0 when the next ASP.NET Preview is released.

# June 16, 2008 6:07 PM

ASP.NET MVC Archived Buzz, Page 1 said:

Pingback from  ASP.NET MVC Archived Buzz, Page 1

# June 27, 2008 4:47 PM

Buy cialis. said:

Buy cialis.

# June 28, 2008 4:28 AM

Turkey said:

Thanx You.. Perfect Docs

# July 31, 2008 2:42 AM

Jon Jackson said:

First of all - thanks again for sharing this. Im a Java developer picking up ASP.NET and this is really helping. Its nice to know that ASP.NET has actually gotten around to focusing on the View a bit with MVC.

I just have 1 question - I know the last release of the Sharp Architecture was only using Spring for DI of DAOs but I was wondering what your thoughts were on Spring MVC as opposed to ASP.NET MVC?

The Spring implementation for Java has very good MVC libraries but because I have no experience with Spring.NET I was just wondering if the MVC implementation for .NET was 'poor' or whether you favour ASP.NET MVC over it.

Since I have Java experience I was wondering whether to go down the ASP.NET MVC approach or to explore the MVC capabilities of Spring.NET - given that ASP.NET MVC is still in its 'preview' state?

Hmm - bit of a long-winded question - sorry about that!

cheers

Jon

# August 4, 2008 1:00 PM

Billy McCafferty said:

I've worked with Spring MVC before...it's a great approach as is Castle MonoRail (which I have more experience with).  But now that Microsoft is backing it's own MVC approach and incorporating a lot of feedback from the development community, it's going to be getting a lot more support from both Microsoft mainstream developers in addition to open source groups...it's generating a lot of excitement and will likely become a standard platform for developing MS apps for the web.

# August 4, 2008 1:38 PM

Gee said:

Im still fairly new to C# and very new to NHibernate but have found the work you've done really useful.  

However I have one question, am I correct in thinking that this is used as a way of abstracting NHibernate away?  If so why are any exceptions thrown by NHibernate not caught and wrapped up in another exception?

# September 9, 2008 7:08 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add
Check out Devlicio.us!

Our Sponsors

Red-Gate!