Observations on Microsoft MVC for ASP.NET
Anyone who’s tried to develop large complex web sites with ASP.NET has likely run into many problems covering the page and control life cycle, view state and post backs and subsequent maintainability including the difficulty in creating automated unit tests.
Microsoft, taking a cue from the popularity of Ruby on Rails and subsequent .NET related efforts such as MonoRail, are embracing the model-view-controller (MVC) pattern and developing something more suited to web development than WebForms which aimed to make web development as similar to Windows development as possible (despite the major underlying differences in architecture).
The prototype, currently named System.Web.Mvc or Microsoft.Web.Scalene depending on where you look, is headed by Scott Guthrie with both Phil Haack and Scott Hanselman involved (sounds like a dream project and team to be involved with) and a preview release (“drop”) is due within the coming weeks.
Guthrie and Hanselman presented Microsoft MVC at the ALT.NET conference which revealed some interesting details buried in the video, my rough observations and notes based on the prototype they showed follows:
Philosophy
- Don’t repeat yourself
- Highly extensible & pluggable
- Use generics to achieve strong-typing without code generation
- Good performance, fast enough for large-scale sites
- Separation of concern for maintainability
- Clean URLs in and out
- Clean HTML
Extensible
- Interfaces used extensively
- No sealed classes
- Plug-in points for view engines (e.g. MonoRail’s NVelocity, Brail)
- Support for Inversion of Control (IoC) engines (e.g. Windsor, StructureMap, Spring.NET)
Compatibility
- Runs on the .NET 2.0 CLR
- Some helper classes require .NET 3.5 (extension methods)
- Normal Request, Response objects (via interfaces for mocking)
- Does not support postback
form runat="server"
- Supports MasterPages, DataBinding, CodeBehind
- Existing .aspx’s are blocked using web.config
Visual Studio
- Solution templates for web project and unit testing
- Full designer & IntelliSense integration
Flow
- Route -> ControllerFactory -> Controller -> Action -> ViewEngine -> View
Routing
- Routes can be defined dynamically and support RegEx URL matching
- IControllerFactory pops out the required IController
- Routing is case insensitive by default
- Support REST, blog engine, Jango style mappings etc. default is /controller/action/parameters
Controllers
- FrontController style
- IController exposes:
- Execute(IHttpContext context, RouteData routeData)
- IViewEngine ViewEngine property
- Some implementations available, all with virtual methods:
- ControllerBase (adds dispatching)
- Controller (Populate parameters into
ViewData["key"]
) - Controller
(Populates parameters by making ViewData type T)
- Attributes
- [ControllerAction] attribute to expose methods as actions (secure default behavior by not exposing helper methods)
- Attribute for output caching
[ControllerAction(DefaultAction=true)]
to override default method of Index
Parameters (to the controller)
- Automatically parsed where a TypeConverter exists
- Future versions will support more complex serialization of types
- Can be nullable – use null coalesce operator for defaults
View Engine
- IViewEngine
IView LoadView(string viewName)
- Implementations include:
- WebFormViewEngine
Views
- IView
- virtual void RenderView(object data)
- Implementations include:
- ViewPage – pick up parameters from
ViewData[""]
in conjunction with Controller - ViewPage
pick up parameters from ViewData as type T in conjunction with Controller
- ViewPage – pick up parameters from
HTML
- Clean HTML generation (have they sorted out the id mangling by MasterPages/INamingContainer?)
- Static HTML class supports Link, PagingLinks and Url methods
- Map to action names using Lambda expressions to ensure follows refactoring, e.g.
string url – Html.Link<ProductController>(controller =>controller.Edit(4);
- Is there a way to follow the default action?
Model/data
- Pagination extension methods extend IQueryable for getting pages of data (skip, limit)
- Pattern for view-update-view cycle
- Object property to form field id mapping available and pluggable, allows
product.UpdateFrom(Request.Form)
Testing
- Easy to write tests by using mock objects (request, response)
- Unit testing framework project (NUnit, MBUnit, xUnit.NET)
Finally
- What’s with ScottGu’s nametag, can the show’s organizers not afford anything more than a Post It note?
- What cool software is Scott Hanselman using to do the screen-cast video/zoom/overlay/highlighting?
[)amien
9 responses