Scott Guthrie and Leaky Abstractions

by jmorris 1/27/2010 7:02:00 AM

Scott Guthrie is well known in the .NET world as being the main architect/designer of the ASP.NET framework. He has a very popular blog which is pretty much a press release blog for all Microsofts Web development technologies: ASP.NET, Silverlight, etc. On top of that he is extremely well respected amongst the .NET community and much of what he say's taken to be absolute "word" on best practices and usage of the Microsoft Web technologies.

One thing about his blog, and which I mentioned above, is that it is less of a blog (commentry, opinion, et al) and more of "press release" platform that the commmunity uses to see what's going on with the various Web technologies. Often times his posts are showcases for the various API's that will soon be released and are very tutorial based:

  1. Here is the feature
  2. This is the problem it solves
  3. This is what it does
  4. This is how you do it

Occasionally he'll post work arounds for various issues that developers are facing with technologies, integration or Visual Studio. However, one thing Guthrie rarely does is give an opinion or directly address the community. That is until this recent post in which he discusses the merits of technological debates and his opinion about them. To be honest I agree with him most wholeheartedly about most of his points, but then he begins to speak specifically about ASP.NET Web Forms and ASP.NET MVC debates and again while I follow him for the most part, at one point he really loses me. This assertion in particluar:

"d) I often find debates around programming model appropriateness and abstractions a little silly. Both Web Forms and MVC are programming web framework abstractions, built on top of a broader framework abstraction, programmed with higher level programming languages, running on top of a execution engine abstraction that itself is running on top of a giant abstraction called an OS.  What you are creating with each is HTML/CSS/JavaScript (all abstractions persisted as text, transmitted over HTTP – another higher level protocol abstraction)." 

What he is referring to here, is really the ongoing debate about whether or not ASP.NET WebForms is a "Leaky Abstraction"...here he is trivializing the argument via hasty generalization: "all things software are abstractions, thus all abstractions are good!" This is simply not true. While abstractions are all around us and for the most part are good, many times the abstraction causes more harm than good and MS has a history of creating these type of abstractions and many long-term developers are leery of such solutions.

To be fair, he does qualify his point with the following statement:

"The interesting question to debate is not whether abstractions are good or not – but rather which abstractions feels most natural to you, and which map best to the requirements/scenarios/developers of your project."

However, I feel that he does this not to clarify his point, but to qualify the agenda of the entire post:  WebForms is a good abstraction! However, after working with WebForms since 2002, classic ASP before that, and ASP.NET MVC now, I (and many others) disagree! I think many parts about WebForms are poor abstractions, in fact I am even leery about some of the newer features in ASP.NET MVC 2, but that's another story.

In fact, most of the poor abstractions that exist with WebForms were put there specifically to "shield" developers from the "complexity" of Web development. For example, in the late 90's there were many, many developers who had never developed anything other than desktop apps. To them, learning another technology such as HTML, CSS, or Javascript was a major blocker in moving from desktop to Web development. WebForms gave them what they thought they wanted: a nice abstraction over HTTP and HTML. Instead of hyperlinks, you got buttons. In place of POST and GET you got postbacks and events. This was all nice and good...for awhile.

However, pretty soon the abstraction became a hinderance. SEO became increasingly important and the ugly HTML the WebForms generated became a hinderance and developers had to clear huge hurdles to get the output clean enough to pass an SEO requirement. If it was possible at all. Additionally, the code behind concept created a great place for developers to combine BL, markup (oh, yes), data access, binding, html behavior (javascript),  hackery, etc... into a single co-dependent layer. Seperation of concerns was rarely (from my experiance) practiced as the framework itself lent itself this collusion of sorts.

In the end you get better and better at simply working around the limitations of the abstraction, instead of learning more about what the abstraction is trying simplify. This is bad in so many ways.

A better way to re-phrase Scott's qoute above would be: "The interesting question to debate is not whether abstractions are good or bad, but if the particular abstraction solves the problem is purports to and whether or not it causes more good than bad. If not, it is a poor abstraction." The debate is not about abstractions, it is about specific abstractions that cause developers more grief than good!

 

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

ASP.NET | Pure Rant

Use System.Web.HttpRuntime.Cache Instead of System.Web.Caching.Cache for Unit Testing

by jmorris 8/24/2009 6:41:00 AM

I ran into an interesting problem today while unit testing some code that depended upon System.Web.Cache where the Cache object itself was instantiated, but the internal dictionary was not. What happens is you end up getting null reference exceptions when you try add, remove, etc. anything from the Cache while unit testing. For example:

 



Kinda dififcult to spot what the issue is since it looks like the error is caused by the "PageTemplateKey" not matching on a cached item, but that's not the behavior of System.Web.Caching.Cache. When an item does not exist, null is returned...so what else could be causing this? The "'ContentFactory.Cache.Count' threw and exception" is the dead give away. The internal cache object was not being created in a non server environment.

For my unit tests I am using the Moq framework and mocking the major players of the ASP.NET HTTP stack. Notice that when I perform the setup on the mockContext object below I am setting the return value to be a new Cache(), this is where I am running into the issues described above.



So what to do now? There are at the least to ways to work around this issue: 1) create a mock cache wrapper or 2) use System.Web.HttpRuntime.Cache as a replacement. Opting for simplicity, I switched out the code on my MakeMockContext method to use System.Web.HttpRuntime.Cache and viola, problem solved:


This worked like a charm:

 



The reason why this works is that System.Web.Cache uses CacheInternal, which you guessed it, is set by an internal setter, called SetInternalCache. HttpRuntime directly makes the call to create CacheInternal when you access the HttpRuntime.Cache property.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , ,

ASP.NET

Rendering Views using ASP.NET Webforms and Model View Presenter (MVP) Pattern and AJAX

by jmorris 5/1/2009 6:49:00 AM

ASP.NET MVC introduces the notion of partial views, which either allow specific Actions to be called on a Controller and the resulting view outputted as HTML or allow Model Data to be passed from the current view to another, child view.

Calling Actions on a Controller and returning “sub” Views is incredible useful in situations were Ajax type behavior is required, since the resulting output is simply raw HTML. The HTML can then be appended to a DOM element via JQuery, some other JavaScript library or simply with straight JavaScript.

Unfortunately if you are still working on Web Forms projects or you have no need or desire to drink the kool-aid of MVC, you are pretty much out of luck for similar functionality built into Web Forms. However, it is fairly easy to implement this sort of behavior within the context of a Web Forms environment and then use a Ajax to render pure HTML from these “partial views.”

The code for doing this is surprising simple and was adapted from a Scott Guthrie posts a few years back:


In this case I allow a Dictionary containing the name value pairs of the properties on the View that will be loaded to be passed in as well. The key must match the name of a Property on the View and if it does the Property is set with the value of the key. This is useful in cases were you would like a parent View to pass data to a child View for initialization situations, etc.

I also have a static collection of Views defined which map a View’s name to a path in my applications root directory. RenderView looks up its path and loads the control before setting the Views data. In my case I load this from a table via a Data Access Object (DAO) in the Global.asax on Application_Start:



The PageUserControlDAO loads the View definitions from the database once when the application is started or the App Pool is restarted/refreshed.

Rendering the View involves calling the RenderView method and passing in the appropriate View name and a Dictionary containing the data to into the view:



In this case I used Page_Load to render the View into a panel (div) which isn’t too exciting. The really useful aspect however is when you combine JQuery and Web Services to render the View on demand from the client.

Rendering Views from the Client Using JQuery and Web Services

The Web Service:



The JQuery code to load the view and attach it to the DOM:


In the JavaScript above, renderView takes three parameters: the name of the View to render, the data to pass to the View, and the DOM container to load the view into. The $.ajax(..) method is a JQuery method that specifies the WebService to use, the method to call (RenderView) and the content type to specify in the request header.

When the method is called like so from the client:

 

renderView('ImageView', { 'CurrentPageElementId': 100 }, $view);


The WebService method is invoked, which renders the view and returns pure HTML that is then appended to the DOM element $view (a simple div or span).

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , , , ,

Ajax | ASP.NET | C# | JQuery | MVC | Personal

Powered by BlogEngine.NET 1.3.1.0
Theme by Mads Kristensen

Jeff Morris

Name of author Occasional rants about software development and software engineering in general.

E-mail me Send mail

Calendar

<<  March 2010  >>
MoTuWeThFrSaSu
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

View posts in large calendar

Pages

    Recent comments

    Authors

    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2010

    Sign in