January 2008 - Posts
I attended an MSDN event the other day - the topic IIS 7. For those of you running Vista you have IIS 7 now. The team has been fixing a few bugs and the new updated version will ship as part of Windows 2008, and as service pack for Vista.
My conclusion - I can't wait to upgrade my web servers to IIS7 - which unfortunately means an OS upgrade as well from 2003 to 2008. Why I am so excited - 2 features, but I will get to that…
First the server is very robust and production ready - 79 of the 80 web servers that are Microsoft.com are IIS7 and have been for a while.
You can build the server you need, not the one Microsoft ships. If you don't need FTP support or windows authentication…don't load the code that provides those features. This means patches can be built quicker, and new features added out of the cycle of the general OS release.
The server now has an integrated pipeline, what does this mean? Well for a start .Net is no longer invoked as an ISAPI extension, in fact .Net is integrated into the pipeline. So you can extend the web server, adding your own Modules and Handlers written in .Net. This allows you to do things like build your own authentication provider which is executed at the beginning of the pipeline. You no longer need to write your own ISAPI filters etc to do low level web server operations.
The Metabase has gone! It has been replaced with a new completely XML file. Another cool feature is that the file can be located via a UNC share. So if you have large numbers of web servers and want to make sure they are all configured exactly the same - have them point to the same configuration file. I have spent so many hours checking things like this when building and upgrading web farms.
A whole new management UI - gone are the tabs - a more MMC approach has been used. This can also be easily extended - new APIs to allow you to build and configure your own web server extensions.
If you build WCF web services and the client was .Net and you wanted to use the TCP bindings or Pipes, but did not want to write a service which had it's own start stop and recycling UI and multi threading support, IIS 7 is for you. IIS7 can host WCF web services which net.TCP and net.PIPE bindings.
There is now a command line interface that allows you to pretty much do anything to IIS7 you would need to do. For example creating a new site, deleting a site. For more information in getting started with APPCMD.EXE see http://www.iis.net/articles/view.aspx/IIS7/Use-IIS7-Administration-Tools/Using-the-Command-Line/Getting-Started-with-AppCmd-exe
For those of you who use Powershell - there is Powershell support for IIS 7. One day I must start digging into this.
So now for the 2 big reasons I want to move to IIS7….
Error logging has been improved, think trace.axd on steroids. Have you ever been in the situation where someone says - "yeah customer had a failed request yesterday, no idea what they were doing.". Well if you use System.Diagnostics namespace and write tracing code etc, then you are in luck. You can now configure IIS 7 to report failed requests - what's a failed request - what you define. You can on a URL basis specify rules on what you consider a failure. So even though a request may complete, it maybe too slow for your SLA. You can create a rule that records the trace output for that request to a disk file. Then you can dig into what went on in the request after the effect.
Now for the #1 reason… Ever wondered "Why is my web server running so slow right now", or "whats running on my server". How many times have you sifted through weblogs after a production issue, to try and work out what requests were causing problems. Well now you can - from a command line:
Appcmd list requests
It will dump for you the URL, along with query string parameters, of every request currently executing on the server and how long it has been running.
IIS 7 has it's own website, the team looked at what other teams in Microsoft have done and wanted in - so check out http://www.iis.net for an enormous amount of information.
There was a very interesting article in the most recent Wired magazine by Tim Hartford, I agreed with a lot of its content. Though the article was not addressing programming and/or software projects in particular, I think it nailed what we've observed in practice when developing software applications, especially in the rapid/agile manner many clients are demanding these days. Working on-site with the client is the best option whenever it's available: An excerpt:
One day, perhaps, virtual communication will become so good we'll no longer feel the need to shake hands with a new collaborator or brainstorm in the same room. But for now, the world seems to be changing in a way that actually demands more meetings. Business is more innovative, and its processes more complex. That demands tacit knowledge, collaboration, and trust — all things that seem to follow best from person-to-person meetings. "Ideas are more important than ever," Glaeser says, "and the most important ideas are communicated face-to-face."
Which explains why the highest-tech industries are the most dependent on geography. In a study published in the American Economic Review, researchers examined 4,000 US-based commercial innovations and found that more than half came from just three areas: California, New York/New Jersey, and Massachusetts. Almost half of all US pharmaceutical innovations were invented in New Jersey, a state with less than 3 percent of the nation's population.
In theory, technology should allow new-economy firms to prosper as easily in Nebraska as in Silicon Valley. But far from killing distance, it has made proximity matter more than ever.
Link to the whole article: http://www.wired.com/culture/lifestyle/magazine/16-02/st_essay
Rather than talk about particular pieces of coding, I like to focus on the few concepts of coding and development, which are universal to any development practice. I recently finished working on a .NET enterprise project recently. It was a typical multi-tiered application with Windows client, Web, and database tiers. I observed some code which was easy to overlook and identified a problem lurking within.
In a multi-tiered application, some code is specific to a particular tier, some is shared across the tiers providing some common services, frame work etc. When developing common module code in a multi tiered application, it is easy to forget and overlook the context in which code will be executed (any of the tiers, potentially).
As an example, a simple piece of code such as (made very simple to embolden the point)
public void LogException(Exception ex)
{
if (!EventLog.SourceExists(ex.Source))
{ // raises exception in Web tier
EventLog.CreateEventSource(ex.Source, "Application");
}
EventLog myLog = new EventLog();
myLog.Source = ex.Source;
myLog.WriteEntry(ex.Message);
}
In a Windows client context and unit tests the code worked as intended by the developer. In a web application context, CreateEventSource would raise a Security Exception. It’s because the web application is by default running under a low-privileged account. Now add a few layers of encapsulation, delegation (typical in an enterprise application) and wrap it around an empty try catch block. You then have no idea what happened when an exception occurs.
When writing common code and the unit tests around it, we tend to forget the context in which the code could get executed. I am not going to explain how to create an event log entry or how to improve the code to better handle these exceptions. There are many web sites that dive deep into event logging and the entire exception handling API. My point, is rather very primal – “know your application running context and consider its ramifications.” Now, why would anybody add an empty try/catch block, especially in an enterprise level application? That’s a topic for another day.
I'm going to write a blog series about Rapid Application Development (RAD) and the advantages of using a custom code generator. Today I'm going to review what I'm going to cover in the coming weeks.
The most obvious question to ask on this topic is this: With all of Visual Studio's drag-and-drop development ability isn't it pointless to develop a custom code generator to begin with? The answer to that question really lies in understanding the difference between developing a working application and developing a production application.
A consultant's job isn't just developing an application that satisfies a client's requirements within a given time and budget (a working application), but in also leaving behind a code base that can be enhanced and extended with just a modicum of effort (a production application). There should be at the very least some basic documentation and the concept of an n-tiered architecture, with each tier easily distinguished from another. Good consultants don't just develop for their client, they also develop for the next developer -- who may very well be themselves if they capture more of the client's business.
Microsoft's RAD tools offer a good number of positives. The Enterprise Libraries, for instance, give current best practices with good examples and documentation. They are easy to add as references in an application and easy to use out of the box. The biggest disadvantage to the Enterprise libraries are that as best practices evolve the library used earlier may be obsolete, so a very necessary first step is to wrap all of the libraries you intend to use into an assembly of your own. This way you can guarantee the interface and change the implementation details as newer methodologies and best practices appear.
Without subclassing in this way upgrades to the libraries may require wholesale updates in your application to keep it current. This isn't just theoretical pondering, the move from the .NET 1.1 framework to the 2.0 framework incorporated the Cryptography and Membership libraries into actual framework namespaces, without having the libraries wrapped switching to the newer (and better) implementations in the framework proved to be very, very painful.
Another problem with using the libraries is that you are stuck with what you get - which in some cases may be more than you really need. This is also the case for many of the drag-and-drop techniques used in Visual Studio - you tend to get everything whether you need it or not. It tends to be hard to read and harder to update and support.
A custom code generator avoids many of these aggravations. You can develop in the way you typically develop. You can implement automatic documenting to a large degree. You can get most of the rapid development pluses (i.e. get up and running fast) with few of the minuses (lack of supportability). You can design it to end up with a readable, easy-to-support and enhance code base.
To do this we'll need to tackle the following areas, which we'll do over the coming weeks.
-
Seperate the UI from the Business implmentation, but decide what type of UI we want to use so that we can develop a concrete example. (I'll use a WinForm)
- Be able to modify the app.config file from within the application
-
Load and save definition files so we only have to define our objects once
Use SQL SMO to do the following:
-
Define a table and have it created in the selected database
-
Create table DDL and persist it to a directory for backup into a code library
-
Create the formatted T-SQL for the CRUD stored procedures based on the definition file
-
Execute formatted T-SQL to create the CRUD stored procedures in the selected database
-
Create integrated InterfaceObject, DataAccess and ApplicationObject (BusinessObject) based on the defintiion file
-
Create a simple application using the code generator to show it in action
-
Define the application so the steps will relate to a concrete implementation instead of an abstract idea
-
Calorie counter (perfect to help with my New Year's resolution)
-
Create a list of features that we'd like to see implemented for future versions