January 2007

Monthly Archive

links for 2007-01-18

Posted by on 18 Jan 2007 | Tagged as: Links

When APIs evolve – or how I lost my lunchtime by installing the .NET 2.0 Framework

Posted by on 17 Jan 2007 | Tagged as: .NET, COM Interop, IIS, SysAdmin

In the presentation about Good API Design I talked about in yesterdays post one of the key points made was that once an API is defined you should never make changes to it that will break your client’s code. An example cited throwing exceptions based on values previously considered fine.

As luck would have it I encountered an actual example of precisely this problem today while installing the .NET 2.0 Runtime on a development server. This server runs a number of .NET 1.1 applications and a number of classic ASP applications consuming COM components written in .NET 1.1.

Things didn’t start well, with the framework installer stopping the IIS instance for the better part of 10 minutes while installing, however it did restart it again once it was done (unlike MSDTC and SQL Server when installing anything from the Windows Components section of Add Remove Programs on Windows 2003).

Matters got worse when someone mentioned that one of the components on the server was now misbehaving – specifically one that uses the ASP.NET Cache to provide caching capabilities.

Whenever a web application tried to create this object (via Server.CreateObject) it was getting an invalid pointer error. Other COM components developed in a similar way were working fine, so I assumed there was something wrong with the registration of the component. Un-registering and re-registering the component gave no joy – neither did calling it from a simple VBScript file.

To make matters worse, a simple .NET test application was working just fine using the exact same library.

After a bit of head scratching and pondering the SysInternals (Now a part of Microsoft) Process Explorer revealed that instead of using the .NET 1.1 version of System.Web both CScript and the IIS DLLHost were loading the .NET 2.0 version. The code for the component hadn’t changed, so maybe the .NET framework had.

Loading the source code for the component into Visual Studio 2005 and attempting to compile and run a the simple test application revealed the problem, a Null Reference Exception from within the framework.

As the COM Component was using the ASP.NET System.Web.Cache it was creating a HTTP Context instance internally. This code looked like this:

private System.Web.HttpContext context = new System.Web.HttpContext(null);

Poking round the disassembled code of System.Web in Reflector didn’t reveal what it was that was causing the exceptions, although I did only go a few functions deep, however it did reveal an alternative way of getting to the cache.

Changing our code to use a call to System.Web.HttpRuntime.Cache to obtain the cache instance fixed our problem, and a quick rebuild of the component against .NET 2 and redeploy to the server and we were back up and running.

Lessons learned from all this:

  • The .NET Framework installer will stop IIS and keep it stopped for a large part of the install – useful to know considering I’ll be installing it on some production servers soon
  • Both IIS and CScript seem to run all .NET COM Components through the most up to date version of the .NET framework, regardless of the version the component is registered or compiled with
  • .NET applications (like our test applet) will run in the .NET framework version they were compiled against if available

Coding for Coders – Good API Design

Posted by on 16 Jan 2007 | Tagged as: .NET, Design, Development

As a developer I am most happy writing code for other developers to write code with. I attribute this in part to the fact that I don’t enjoy writing user interface code as much as writing the code that no-one sees. For me, my favourite user interface is an API or even a web service.

One of my favourite books about APIs is Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries by Brad Abrams and Krzysztof Cwalina. I’ve been reading Brad’s Blog for quite some time and today he posted a link to a really good presentation by Joshua Bloch about designing good APIs. The presentation is video with the full slide deck, and covers a range of topics from the initial specification of an API, through implementation considerations with some specific references to good and bad APIs. I found the parts about specification of an API and avoiding implementation details leaking into the published API and controlling the interface of the API.

Things I took away from watching the presentation:

  • Consult people about the specification – get as much input as possible before committing to a design
  • Keep the interface simple – over complication makes using the API confusing – Usability is important for APIs, stick to naming conventions already in use for your platform
  • Control what you expose – don’t let internal implementation escape through your API, control the exceptions and types you expose
  • Documentation is important – make sure all public parts of the API are documented, the level of reuse of your API will be defined by the how good the documentation is
  • Consider performance of your API – make sure its not going to cause any horrid performance characteristics
  • Subclass only when the type is really a sub class of the parent type (Liskov Substitution Principle)
  • Don’t make the client do work if the module can do it for you – avoid the need for boiler plate code to use your API
  • Report errors as early as possible – compile time is best, runtime is worst
  • Be careful about your parameters – use the most appropriate types, keep the number of parameters under control, make sure overloads are obvious
  • When throwing exceptions give as much information about why the error occurred as possible

The list above is not exhaustative, I highly recommend watching the full presentation – its well worth the 68 minutes it will take.

« Previous PageNext Page »