Display Placeholder

By Ryan at October 21, 2009 10:55
Filed Under: Development

Whilst playing with MVC 2, I came upon the need to display an element that I could later replace as the result of an AJAX callback.  Starting with the DisplayFor<> HtmlHelper extension, I found that it simply outputs the given value as a string, with no way to later replace it.  I could create a custom display template, but I wanted more fine-grained control.

So, I decided that needed some way to create a display element wrapped in a <span> tag.  With a <span> tag and an id, I would be able to display the model-bound data, but later replace it as the result of a AJAX callback.

This is what I came up with:

   1:  /// <summary>
   2:  /// Creates a placeholder element displaying the value given by <paramref name="display"/>.
   3:  /// </summary>
   4:  /// <typeparam name="TModel">The type of the model.</typeparam>
   5:  /// <typeparam name="TValue">The type of the value.</typeparam>
   6:  /// <param name="html">The HtmlHelper being extended.</param>
   7:  /// <param name="display">The property from the model to display.</param>
   8:  /// <returns>An <see cref="MvcHtmlString"/> containing the display value wrapped in a &lt;span&gt; tag</returns>
   9:  public static MvcHtmlString PlaceholderFor<TModel, TValue>( this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> display ) {
  10:   
  11:     return PlaceholderFor( html, display, null );
  12:  }
  13:   
  14:  /// <summary>
  15:  /// Creates a placeholder element displaying the value given by <paramref name="display"/>.
  16:  /// </summary>
  17:  /// <typeparam name="TModel">The type of the model.</typeparam>
  18:  /// <typeparam name="TValue">The type of the value.</typeparam>
  19:  /// <param name="html">The HtmlHelper being extended.</param>
  20:  /// <param name="display">The property from the model to display.</param>
  21:  /// <param name="htmlAttributes">The HTML attributes.</param>
  22:  /// <returns>An <see cref="MvcHtmlString"/> containing the display value wrapped in a &lt;span&gt; tag</returns>
  23:  public static MvcHtmlString PlaceholderFor<TModel, TValue>( this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> display, IDictionary<string, object> htmlAttributes ) {
  24:   
  25:     ModelMetadata metaData = ModelMetadata.FromLambdaExpression( display, html.ViewData );
  26:     TagBuilder tag = new TagBuilder( "span" );
  27:     tag.GenerateId( metaData.PropertyName );
  28:     if( htmlAttributes != null ) {
  29:        tag.MergeAttributes( htmlAttributes );
  30:     }
  31:     tag.SetInnerText( Convert.ToString( metaData.Model, CultureInfo.CurrentCulture ) );
  32:     return MvcHtmlString.Create( tag.ToString( TagRenderMode.Normal ) );
  33:  }

Mixing solid design with code generation

By Ryan at October 09, 2009 08:47
Filed Under: Development

One thing about a good software design is there usually exist a number of layers of abstraction.  The problem is that this can start to become cumbersome to manage.  It's important, however, to recognize that there are tools out there to mitigate this and thus your design shouldn't suffer as an attempt to "simplify."

Simplification comes through abstraction and encapsulation.  If you find your architectural framework complex, you're probably not encapsulating the details enough.  I always design with a junior programmer in mind.  That is, could a junior-level programmer pick up my code and be productive in a short period of time.  If the answer is yes, then the design is "easy" to work with, though it may be "complex" under the covers.

The first way to simplify any design and the inherent testing thereof, is to use an Inversion of Control (IoC) framework.  There are many on the market (Spring, Unity, Castle Windsor, etc.)  Such frameworks allow for clear separation of concerns without hard-coding dependencies.  The real benefit is realized when unit testing.  Without an IoC framework, you'd (hopefully) do dependency injection manually, however this would require lots of plumbing to test a single component and lots of manual work.  IoC containers make this easier by "automatically" managing the dependency instantiation.  I great tongue-in-cheek overview can be found here.

Given all of that, I sometime still struggle with the perceived complexity of my code.  Most if the complexity (with respect to dependencies and separation of concerns) happens in the lower layers, from the service layer down.  Fortunately, most of this has a one-to-one mapping to a database.

Let me preface the following by saying that this only applies to websites, as opposed to shippable products.

Now, call me old-fashioned, but I don't like ORMs.  Well, more specifically, I don't like ORMs when there's little chance of a change to the underlying datastore provider.  I don't feel like I get the level of control that I want, and, given my experience perf-tuning applications for production, I feel that I'm justified.  I say this because the ORMs abstract away the database interaction and, following my "junior developer" thought process makes it easy for developers to write horrible data access code.  I feel it's of much more value for a junior developer to become familiar with a particular database vendor (SQL Server in the .NET world, for instance) than an ORM that may or may not be used at the next job they get.  If you understand how the underlying system works, you can then work at a higher level with getter effectiveness.

So, in order to achieve the same effect of an ORM, I simply use code generation.  This is far simpler in .NET than in Java to due to certain language constructs.  By generating the code, I don't waste CPU cycles at runtime as various mappings and pseudo-SQL expression are worked out.  I simply send the query to the db provider.  Sure, this SQL could be vendor-specific, but I find that 90% of the time, I can write ANSI SQL query that SQL Server, Oracle, MySql, DB2, etc could process.  You might say, however, that I am limiting the reusability of my code.  I'd argue that proper separation of concerns shields me from this.  I have never reused data access codes across projects since the data model always differs.

Now, the game changes if I'm building a product.  In this case an ORM is, by far, the best way to support multiple DB platforms.  It's worth noting that even with an ORM, there's still a lot of plumbing and data containers that the ORM maps which should be generated.  Anyone that is hand-writing files that correlate to a database table need are stealing from their customers. 

In the end, this comes down to using the right tool for the job.  I feel that code generation of potentially native SQL is the right tool for a single-db-platform website and, in contrast, ORMs are the right tool for shippable products that can live on any platform.  In both cases, though, code generation should play a role in the development process.

Uninstalling VS 2008

By Ryan at October 06, 2009 10:29
Filed Under: Development

As any VisualStudio user knows, the VS installer includes a bunch of separate product installs.  The problem is that when you want to uninstall VisualStudio, it leaves all of those "value add" products installed.

I was retiring an old development machine and started removing the components before running the main uninstaller.  Well doing this screwed up the VS installer causing the "A problem has been encountered while loading the setup components. Canceling setup." error.

In trying to solve this issue I found a handy tool provided by Microsoft which will undo the havoc that it had wreaked on your machine.

Behold, the AutoUninstallTool.

ASP.NET WebForms vs MVC

By Ryan at October 06, 2009 08:23
Filed Under: Development

This is from an email that I sent out trying to elaborate on why I chose MVC over WebForms for my latest side project.

I wanted to come back to the discussion we had yesterday about the differences between MVC and WebForms.  I don't dislike WebForms, they have their place, I just feel that they are more suited to a form-centric, "business application"-type web application.  I suppose this is because WebForms do a good job of collecting data in a simple way; public websites need to provide a more rich user experience (to meet current user expectations) that seems to be difficult to achieve out-of-the-box with WebForms.

I see WebForms as a component-based model, where MVC is an object-oriented model.  As such, we've seen the ViewState in WebForms require lots of work-arounds in the [our legacy code], for example, because as soon as you try to combine the object-oriented world with the component/event-driven world, there's a mismatch.

Now, as I see it, the decision to use MVC will mean that we lose

  • Drag-and-drop page construction
    • As we've seen, you lose that pretty fast as soon as you do anything half-complicated. 
  • ViewState, but, as we've seen, this has caused problems and required work-arounds in the past.
    • We don't lose statefulness, just the viewstate and the goofy generated IDs
  • Solid componentization
    • There are components and reusable UI elements in MVC, but not a solid as WebForms
  • The abstraction of HTML and CSS
    • Sorry, you'll need to know HTML and CSS, but I'd argue that you SHOULD know HTML and CSS if you want to call yourself a web developer (unless you only want to ever work with webforms, only in .NET - why would you limit yourself?)


On the flip-side, we'll gain:

  • More consistent object-oriented development
    • Better testability (find a bug, fix it once, and have a test to make sure it never shows up again, BDD)
    • Better decoupling/separation of concerns
  • More control over presentation
    • More granular control over markup
    • Better statefulness (using client-side javascript and AJAX)
  • More marketable skills
    • Knowledge of another Microsoft framework
    • Better knowledge of what good HTML looks like
    • Better understanding of CSS
    • Better understanding of the DOM
    • Better understanding of cross-browser compatibility
    • Better knowledge of how HTTP actually works ;)

Lastly, since you've made me do it, remember those Telerik controls that we used for [the last revision of our .NET app]?  Yeah, they'd work with MVC too:

http://www.telerik.com/products/aspnet-ajax.aspx

Microsoft ASP.NET MVC - ready
With RadControls you no longer have to stick with simplistic UIs in your MVC Views. Telerik UI controls support Microsoft MVC and allow you to combine the testability and separation of concerns of the emerging technology with the richness of traditional ASP.NET server controls. See demo or visit our MVC Forums

Hopefully this has convinced any skeptics that the decision to ASP.NET MVC is a good one.

Code Formatting Extension

By Ryan at October 05, 2009 21:31
Filed Under: Meta

Found this site describing how to get the CodeFormattingExtension for this blogging engine to work.

The format for the extension is:

[code:c#|vb|js|html|xml|tsql|msh;ln=on|off;alt=on|off]

   Put your code snippet here

[⁄code]

Building a New Site

By Ryan at October 05, 2009 21:00
Filed Under: Development

I working on building a new website in my spare time.  I've decided to use this opportunity to play with ASP.NET MVC.  I put together a long list of pros and cons for ASP.NET WebForms versus MVC; perhaps I'll post it.

 

Anyway, when I started laying the groundwork, I went with the RTM version of MVC (v.1), but I was too compelled by the upcoming of features of v2 that I decided it makes sense to throw caution to the wind and lay down the UI framework with it.

 

I haven't had a chance to really dig into the MVC framework; thus far it's been all backend code.  Every now and again, you've got to start an application from scratch to make sure your you're keeping your skillset fresh.  The hardest part of being a developer is creating something from scratch.  After the initial creation, it's just a matter of plugging in functionality and fixing bugs.

 

I will try to treat the blog like a journal for my adventures with MVC, and any website launches that may, or may not, be on the horizon.

New Site

By Ryan at October 05, 2009 16:17
Filed Under: General

I've switched blog engines to one that is a bit more sane.  I feel this will compel me to blog more frequently; I just need to get into a routine.

About Me

thumbnail I'm a software developer currently employed by Pearson (PSO/PSON)* where I work with, my passion, .NET.  I have (close to) two decades of programming experience and I'm constantly trying to learn new languages, technologies, practices, etc.

 

Disclaimer

* Emerle.net is owned and operated by Ryan Emerle. The views expressed on this blog are his personal opinion and do not necessarily reflect the views of his employer or clients.

The same holds true for comments posted to Emerle.net; they are the comment posters' personal opinion and do not necessarily reflect Ryan Emerle's views or the views of Ryan's employer or clients.