Blogs

Intelligent Design

Wrestling an Enterprise Architecture out of .NET

As a growing "Software as a Service" (SaaS) development shop using .NET we've encountered many growing pains and some of the speed bumps inherent in the architecture that many others probably have as well.  I'd like to express some of the issues we've encountered and hear if anyone else would like to start a dialog on the shortcomings and potential solutions to scaling enterprise .NET development. 

The bigger the code, the bigger the problems 

The typical architectures espoused by .NET aren't well-designed for large, "always-on" apps.  This has become clear to us as our development group and our codebase have grown.  SaaS is a big factor here as well, since best-practice is quickly discovered to be a rather tight, incremental release schedule.  As our development group scales, and feature demands increase, the framework everything is written in begins to show its strengths and weaknesses.  It's the sort of thing that is difficult to see until many hands have been in the same pot over a period of years.  J2EE seems much more geared towards large, enterprise apps, with more emphasis on strict contracts and black boxes.  While many of the Java frameworks seem like overkill to most .NET developers, it's because most .NET developers don't work on the same codebase for more than a year or two.  It seems like Microsoft has made a calculated move to aim squarely between the enterprise and the PHP-type developer communities.  We love .NET tools though, and are looking at some foundational architecture changes to tackle these issues.

Misplaced intelligence 

One of the key difficulties introduced with .NET is the Page-Controller Pattern.  Despite how nice and elegant the most common n-Tier .NET architecture sounds on paper, practice shows that a great deal of intelligence (WAY TOO MUCH intelligence) inherently ends up in the code-behind of your pages and user controls, and thus, smack in the middle of your presentation layer.  This produces a tight coupling between the presentation and business layers and a lot of business logic in the wrong place.  The commonly espoused reason for decreasing this coupling is the ability to completely change the UI layer - say, to take your existing business layer that you used with your Web pages and slap WinForms directly on top of it.  While this would be wonderful, the more pressing reason is the simple need to refactor code for maintainability and extensibility.  Anything in your code behind pages cannot be reused elsewhere.  While having nice business methods in your business layer like "FetchOrdersByCustomer", or "UpdateProducts" that deal with nice typed objects and collections may make you feel all warm and fuzzy because you have your n-tier bases covered, your architecture bases really aren't covered at all.  Or maybe you have your entities possess the intelligence to manipulate themselves.  Either way, the majority of custom development occurs within the consumers of these methods.  If the consumers of these methods are in your code behind, you will have real problems as your product grows, your development team grows, and the demands on your product begin to pull it in multiple directions.  What you really want is an incredibly stupid presentation layer that only has intelligence about itself.  It should only know how to present information from a strictly contracted model it knows nothing about manipulating, how to manage state between "locations" (pages, winforms, pocketPC forms, etc), and how to handle client-side behavior.  This is another argument for stupid entities as well (our entities do not know how to manipulate themselves), since our presentation layer can reference our entities without having to worry about exposing all that business logic to the presentation layer.  I'm sure I'll get some disagreements on that, but that's the beauty of hearing other people's opinions.

A possible solution

The solution we are developing is moving towards something closer to the Model View Controller pattern.  Particularly MVC2, which is the same pattern altered for the web.  Microsoft's User Interface Application Block is an MVC block, but MVC does not work on the web.  MVC depends on the View being directly updatable from changes to the model, so that combined with the complexity of that application block make it unfeasable for our use.  Since the web is stateless, there is no way to directly update your UI from changes to the model.  What MVC2 does is simply insert the controller into the process coming from both directions (web to model, and model to web).  Microsoft has no packaged solution for anything close to MVC2, which is really disappointing, since you would think they'd want to compete more directly with J2EE and fill this gaping architectural hole.  There are some packaged solutions from third parties (even more evidence of a serious development need unmet by Microsoft), such as Maverick.NET http://mavnet.sourceforge.net/, MonoRail http://www.castleproject.org/index.php/MonoRail, and something called NWAF http://sourceforge.net/projects/nwaf, but all of the above take rather radical departures from the .NET way of doing things and are a big jump for .NET developers.  Things like the basic page lifecycle and ViewState are radically changed.  We wanted something that wasn't quite a big leap for our group, yet still gave the major benefits of MVC2. 

There has been a pattern that has recently risen to the top of the .NET pattern circles called Model View Presenter (MVP) that attempts to take a stab at MVC2 and still maintain WebForms and ViewState management.  I've recently read a few articles that mention Microsoft's CAB (Component UI Application Block) will have some MVP patterns in it, but we're not holding our breath.  It's also targeted at Smart Clients, so I don't know how practical it is for pure web-based apps.

We're building our own home-grown version of an MVP architecture for all development going forward. We are also baking in a few more things that we feel are important, such as:

  • Typed navigation - urls should never appear in code, and it would be nice if the developer knew the exact state data required in order to navigate to that location/view at compile time
  • Removing all state-management concerns from the Controller layer - controllers should not care anything about how state is persisted or even have to make the decision that something should be persisted.  They should just be able to expect the properties on the View to be available.

As we get further along, I'll post some of the pitfalls and breakthroughs we come across.

 

Published Friday, September 22, 2006 6:24 PM by thardy

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

tgrimm said:

Tim, Very interesting view. I've in software development for over 20 year and in .NET for the last 3 or 4, but I have never thought about this concept. Kinda blows me away. I'd love to hear more and see how this works with FS1. TG
December 5, 2006 9:40 AM
 

thardy said:

It's been awhile since my last post on the architecture (that's because we've been writing it), but I plan to talk about typed navigation this week. There've been some rough spots, but I think the end result is going to be well worth it.
December 11, 2006 4:22 PM
 

Intelligent Design said:

If you were following our blog at the end of last year, you read my entry on MVC - Wrestling an Enterprise

October 31, 2007 8:11 PM

Leave a Comment

(required) 
(optional)
(required) 
Submit