Thursday, November 30, 2006

NUnit and Visual Studio 2003

In any typical application that I'm asked to develop, there is an assembly of business objects I'm compelled to unit test. So I create a new project to the solution with ".Test" appended to the name (e.g to unit test the CDMA.Business assembly, I'd create a new CDMA.Business.Test class library project that references both the CDMA.Business and nunit.framework assemblies). Frequently, the subject of unit tests depends on application configuration settings, so I'll create a new file called CDMA.Business.Test.dll.config (note that this is the name of the assembly, with ".config" appended) within the test project and then I'll add a new Post-build event to copy the file to the target directory. Project Properties -> Common Properties -> Build Events -> Post-build Event Command Line:

xcopy /y "$(ProjectDir)$(TargetFileName).config" "$(TargetDir)"

To enable debugging via the F5 key, I'll use the following settings in Project Properties -> Configuration Properties -> Debugging:

Debug Mode: Program
Start Application: C:\Program Files\NUnit 2.2.8\bin\nunit-gui.exe
Command Line Arguments: CDMA.Business.Test.dll

If you then set your unit test project as the start up project you can just press the F5 key and Visual Studio will automagically build the project, copy the configuration file, run the nunit-gui executable and attach the debugger to it. To skip the last step, just press CTRL-F5 instead.

Sunday, November 19, 2006

C# 3.0

Ted Neward explains how the new features are nothing more than syntactic sugar that makes programmers' lives a little easier. For example, all the IL code produced by the C# 3.0 compiler can be reverse engineered by Lutz Roeder's .NET Reflector to show you how the feature's actually been implemented. Brilliant.

Wednesday, November 15, 2006

Extension Methods to the Rescue

Today I added some caching to a prototype application I'm developing at work. Microsoft Enterprise Library was my implementation library of choice, but I was frustrated by the choice of available overloads for CacheManager.Add(). Rather than add my own overload, spoil the clean interface and recompile the assembly, I ended up writing a single method on a static class that took an instance of the CacheManager, key, value and expiration as parameters, adding in the default values in a call to the CacheManager object. Now this may not be object-oriented, but it's very similar to how extension methods work in C# 3.0 (in my opinion, they exist solely to _fake_ the object-orientedness in calling code). In fact, when you declare a class like this:

public static class CacheManagerExtension
{
public static readonly TimeSpan DefaultAbsoluteExpiration = TimeSpan.FromMinutes(5);
public static void Add(this CacheManager cacheManager, string key, object value, TimeSpan absoluteExpiration)
{
cacheManager.Add(key, value, ..., new AbsoluteExpiration(absoluteExpiration), ...);
}
}


the new C# 3.0 compiler (figuratively speaking) recognises the "this" keyword in the parameter list, and marks the method, class and assembly with the ExtensionAttribute custom attribute. Now, you can call the Add method like this:

cacheManager.Add(key, value, CacheManagerExtension.DefaultAbsoluteExpiration);

and the compiler (and hopefully Intellisense) - upon realising that no method with that signature exists on the CacheManager class - will translate it into a call on the static class marked with the ExtensionAttribute attribute.

Oh yeah, and my other gripe with Microsoft Enterprise Library is the fact it's caching is not aspect-oriented, but that's the topic of another post...

Post-script: Don't blindly assume that your service delivery team are happy to install EntLib on the production server. :-)

Using log4net

log4net is my recommended lightweight tool for emitting log statements from .NET code. I'm a firm believer that application users shouldn't see exception messages or stack traces - that information is for system administrators and developers only. I like storing log information in a database or in a text file on the server and allowing developers to view it when things start to go pear shaped.

Here's how I typically set up log4net on a project:

- Create a sub directory within your solution - called 3rdParty - and copy the log4net assembly there. This allows meto store one copy of the assembly, and reference it from all projects in the solution.
- Create a separate configuration file that I call log4net.config (I don't use Web.config or App.config)
- Use the XmlConfigurator custom attribute on the assembly that will be loaded first
(Don't forget to set the Watch property to true)
- Start appreciating the benefits of logging!

NOTE 1: If you do choose to use Web.config or App.config, the only reason you have to declare the IgnoreSectionHandler is for .NET to ignore the log4net section!

NOTE 2: No, I don't know what line of code causes the XmlConfiguratorAttribute to be reflected and subsequently configured.

Tuesday, November 14, 2006

C# 3.0 is not dotnetfx3; repeat;

I am a little behind the times, it seems, as Microsoft released .NET Framework 3.0 just a few days ago. Luckily, the release is true to it's name - it's just another version of the framework with the recent additions WCF, WWF, WPF and CardSpace(collectively and formerly known as WinFX). It contains neither C# 3.0 nor LINQ, both of which will be released with "Orcas". Phew. That means I have time to brush up on my knowledge of automatic type inference before a random client starts asking tough questions!

Sunday, November 12, 2006

Technical Forum

If I could offer you only one tip for the future, ______ would be it. I've tentatively accepted a spot to speak on a technical subject at a forum of consultants, but I haven't yet chosen the topic. It's my first foray into the world of presentations; I don't expect it to go swimmingly but if I can judge the level of my audience and give them something useful then my job will have been done. Actually, I will judge it a success if the audience can go away and apply some practise they learned from me (or were inspired to learn by the topic).

To meet this goal, the focus needs to be on both the content and its delivery. I hope I can do it!

Exception Handling

OMF! My blood reached boiling point this week when I overheard a colleague whining when his poorly structured error handling and logging mish-mash was removed from the codebase. Similarly, it boiled a couple of months ago when a group of fellow consultants were encouraging a user interface element that would generically display stack trace information to users. Please, people, follow these guidelines:
a) Stack trace (or even exception type information) should NEVER be shown to users because you don't know what kind of sensitive (perhaps proprietary) information is contained within.
b) DON'T append long dynamic SQL statements (or any other information used solely for diagnostic purposes) to your Exception's Message property so that it can be displayed on the screen, unencrypted, rather log it separately.
c) DO use a framework like Microsoft's Enterprise Library, or a component like log4net to trace information rather than displaying it in the end user's UI.

Sunday, October 29, 2006

Inertia Xenon

I released the first alpha version of Inertia Xenon - my lightweight .NET grid framework - this afternoon. Now that it's out, I need to focus my attention on the parts that require it the most. Initially, I feel that the proxy between the client and service broker could be made a lot better if I baked in a whole lot of multi-threading goodness. Next, I bet my job will be focused on improving the administrator API. Anyway, that's all just speculation. Try it out today and let me know what you think..

Tuesday, October 17, 2006

Defining Architecture

I'm recently attended one of a series of sessions aimed at developers who are aspiring technical architects. From previous experience, I'd decided that the IEEE definition of architecture (presented below) is spot on; now I just wish that others would subscribe to the same idea.
Architecture is the fundamental organization of a system embodied in its components, their relationships to each other, and to the environment, and the principles guiding its design and evolution. [IEEE 1471]
It bothers me when junior developers use the word to buff up their resumes. It bothers me more when experienced developers are called Technical Architects by their consultancy; they should know better. Architects, by my definition, are those people who specialize in architecture as a profession. They are not the people who can recite a few patterns and have skimmed through a couple of Martin Fowler's books (although both of these traits might be present in a real architect). Hmmm. Let's see if the next session is any better.

Thursday, September 21, 2006

Services Share Schema and Contract Not Implementations

It hit me like a 10 ton truck, while trying to architect an grid computing framework for Microsoft .NET that will be service-oriented. It is wrong for a client of a service to depend on any behaviour of its own implementation of, for argument’s sake, an input parameter. The initial grid’s design saw heavy usage of the Command pattern to pass not only data but behaviour across the service boundary. It all falls apart however as soon as you have to make the service boundary more explicit (i.e. J2EE servicing .NET clients) – at that point I realized I needed to revisit the four rules for service-orientation. I now know why wsdl.exe generates you a new set of data transfer objects ... and why SOAP defines request and response messages the way it does. And it's all becoming very clear to me, and funnily enough typing this blog reminded me that this was an interview question I was asked over a year ago by Josh! I’m going to stick the four tenets of service orientation on Post-It notes to my monitors.
Boundaries are explicit
Services are autonomous
Services share schema and contract, not class
Service compatibility is based upon policy

Friday, September 08, 2006

Other Side of the Fence

Phew! I've passed the Java certifications in JSP, Servlets and EJB and can now return to the normal way of life using Microsoft technologies to my heart's content. I'm keen to get back to IIS although I wouldn't mind working with some of the J2EE application servers to see value-add features that each vendor has been able to provide (all my exposure so far has been to Sun's bare bones reference implementation). Expect more Microsoft-related posts soon!

Thursday, August 31, 2006

Throttling Paradox

Who would have thought that you might need to throttle an application server in order to maintain a performance-level contract? I've seen the option inside IIS but couldn't for the life of me think why anyone would want to turn it on. However, in the context of an application that's been through some sort of capacity planning process (so we have a rough idea of how many requests/responses the application can process), and where all requests need their responses within some limited duration (think high-volume/low-latency trading platforms), you can apply throttling to help enforce the performance level. Without throttling, additional requests might be satisfied only to the detriment of other requests already executing on the application server. Ideally, it should be used in conjunction with load-balancing across a cluster of servers, so that throttled requests aren't queued, but rather dispatched to another less-busy machine.

Friday, August 18, 2006

Rfc2898DeriveBytes

Gone are the days of salting and hashing users' passwords and storing the salt and salted hash next to each other in a database. .NET 2.0's new Rfc2898DeriveBytes class derives a pseudo-random key from a password, salt and a number of iterations - a so-called iterated and salted hash. And, apparently, it's more secure than just hashing a password and salt. More info here.

Wednesday, August 09, 2006

CAFEBABE

I just noticed while studying for tomorrow's exam that every Java class file begins with the so-called magic number 0xCAFEBABE! Quite funny, especially since the guys who penned it into the class file specification did so before the language was even called Java. You can find more information at Artima.

Thursday, August 03, 2006

.NET 2.0 vs. Java 5

Type erasure, reification and synthetic bridge methods: yuck. I'm stuck on the proverbial consultants' bench so I decided - after 4 years of non-Java development - to upgrade my Java certification to the latest version in just five days. I honestly thought I was going to make the deadline until I hit the section on generics. Now I'm a half-day behind and my head hurts! C# is way easier to grasp, and from the looks of things performs a whole bunch better too (except for the JITed type instance "explosion" if you really care).

Anyway, since Java 5, the Class class in package java.lang is a generic class whose type parameter denotes the type that the Class object represents. Previously, compilers wouldn't let you compare an Integer and a String. Now (since Tiger) they won't even let you compare Integer.class and String.class! It stems back to the fact that (similar to C#) both GenericType<A> and GenericType<B> do not derive from each other, even though type B extends type A. There's a little bit of extra trickery in the Java though, because both GenericType<A> and GenericType<A> extend GenericType<?> (unlike C# where they derive from System.Object.) This means that you CAN compare a GenericType<capture of ? extends Object> with a GenericType<capture of ? extends String>! Madness.

Thursday, June 15, 2006

I've moved

I've made a fresh start over at Revolución Análoga for all non-technical blogging. Follow the link, you know you want to.

Friday, June 09, 2006

Ramblings of a Bemused Consultant

If people believe that they get what they paid for - and they do, just look at the type of people who buy into the brand of Mercedes Benz - then a well known consultancy brand can leverage this fact to sell its consultants' time for a premium - and they do, just look at how much you pay for an hour with an Accenture consultant. Expanding on this, where should that additional revenue end up? Well, to grow the brand you really do need better consultants, and if your consultants are struggling to pay off mortgages and other financial debt then they certainly won't be able to give 100% of their attention to their work. There's logic in saying that the additional revenue should go back to the consultant: clients would see the exorbitant fees and similar lifestyle of the consultants and would be inclined to buy into the power of that consultancy's brand. In short, if you're running a consultancy, don't fall into the trap of paying your consultants less because you managed to "negotiate" a good deal with them - you will be destroying the power of your brand.

Saturday, May 27, 2006

Angry Worm


"Tape worms that escape from the bottoms of mexicans just don't know how to smile."

Wednesday, March 22, 2006

HTTP Compression in IIS 6.0

The things that nobody told you about HTTP compression:
1. It only works when over HTTP 1.1; however Internet Explorer's default setting is to downgrade your HTTP version to 1.0 if you're accessing the server via a proxy so even though you may think you're compressing the .aspx pages - you are not.
2. Some client programs (i.e. Adobe Reader) don't behave correctly when opening up inline documents (i.e. opening up the document in the browser window) when the content has been transferred as a chunked/compressed stream.
So, when you're testing HTTP compression, use a product like ieHttpHeaders to verify that your results are actually being compressed (you'll see headers like Content-Encoding: gzip, and Transfer-Encoding: chunked), and make sure it works with and without a proxy.

Monday, March 13, 2006

IIS Worker Process Recycling and Prime Numbers

To prevent all your application pools from recycling at the same time ... you should follow the way of the cicada! No I haven't been smoking crack. The theory goes like this: if you have two application pools recycled every M and N hours respectively (where M and N are both prime) then their recycles will only coincide every M x N hours. So, for the default 1740 minutes (29 hours) and the next prime up (31 hours), you're only going to have the problem once every 37ish days!

Friday, March 10, 2006

WindowsPrincipal.IsInRole(...) and cached SID

There is something sinister here that I'm just not getting. There is an ASP.NET 1.1 application under IIS 6.0 with an application pool set to run under the context of a domain user. The application is removed so that we can upgrade it. The domain user is added to a machine local group with additional privileges. A new version of the application is installed and started up. Somewhere in its code the line
WindowsPrincipal.IsInRole(string)
is called (the parameter is the name of the machine local group), but that call fails. The event log shows a success audit for a logon attempt using explicit credentials, but the user's group membership isn't refreshed (even after an iisreset) until the machine is rebooted. If a SID is being cached, it can't be IIS that's doing it, and I'm tempted to believe it's Windows.

Thursday, March 02, 2006

SELECT TOP N

To return only the top N rows in a SQL select statement, it is possible to parameterize the number N in both SQL Server 2000 and SQL Server 2005; you don't have to select the whole result set into a temporary table and whittle down the rows by yourself.
For SQL2K:
SET ROWCOUNT @NumberOfRows
SELECT * FROM SomeTableOfYourChoice
SET ROWCOUNT 0

and for SQL2K5
SELECT TOP(@NumberOfRows) FROM SomeTableOfYourChoice

Monday, February 27, 2006

NTFS Access Control Lists and Inherited Permissions

When you deploy simple changes to your ASP.NET web application / XML web service (like copying in a new web.config file) watch out for cut-and-paste versus copy-and-paste! As it turns out, copying the web.config file will allow inheritable permissions to be applied to the new object - cutting and pasting the web.config will not. If IIS_WPG loses permissions to read the web.config file you'll see the error message: "Server Application Unavailable."

Monday, January 16, 2006

XML Web Service Authentication Failures

Ok, this is just because I'm a geek. Next time you get HTTP 401 errors when you try to invoke a web service call using a Visual Studio generated proxy, don't forget to assign System.Net.CredentialCache.DefaultCredentials to your proxy's Credentials property. Also, ensure that the Windows Integrated Authentication checkbox is selected in IIS, and that the .asmx and CodeBehind files of your web service have read and execute NTFS permissions for your client user. FYI: The best practice is to assign the permissions to the folder in which the virtual directory resides, and allow the children (i.e. the asmx files) to inherit the permissions.

Friday, January 06, 2006