Wednesday, November 29, 2006

XmlDiff

I had to compare two xml files today. This is trickier than you would at first think. Luckily Microsoft has a neat tool, XmlDiff that makes it quite easy. It can compare two files, or two XmlReaders or even fragments. Also it can spit out an xml diffgram so that you can examine and re-apply any changes. Just use it like this...

[Test]
public void XmlDiffTest()
{
    string source = "<root><child1>some text</child1><child2>more text</child2></root>";
    // note some whitespace, child nodes in different order, comments
    string target = "<root> <!-- I'm a comment --> <child2>more text</child2> " + 
        "<child1>some text</child1>  </root>"; 

    XmlReader expected = XmlReader.Create(new StringReader(source));
    XmlReader actual = XmlReader.Create(new StringReader(target));
    StringBuilder differenceStringBuilder = new StringBuilder();
    XmlWriter differenceWriter = XmlWriter.Create(new StringWriter(differenceStringBuilder));

    XmlDiff diff = new XmlDiff(XmlDiffOptions.IgnoreChildOrder |
        XmlDiffOptions.IgnoreComments |
        XmlDiffOptions.IgnoreWhitespace);

    bool areDifferent = diff.Compare(expected, actual, differenceWriter);
    Assert.IsTrue(areDifferent, string.Format(
        "expected response and actual response differ:\r\n{0}", differenceStringBuilder.ToString()));
}

Friday, November 24, 2006

Playing with the XmlSerializer

Have you ever worked on one of those projects where everything is a huge XML document and the code is littered with string literals containing XPath queries? It's a nasty hole to dig yourself into and it's easy to end up with very brittle and fragile application where the structure of your data is baked into hundreds of string literal XPath queries that aren't checked until run time and are a nightmare to change if your data structure changes. You loose all the benefits of OO, no refactoring or encapsulation and condemn yourself to a life of stepping through the debugger and examining the watch window trying to work out which of your hundreds of concatenated XPath queries aren't quite right.

There's a better way and that is to use xsd.exe to generate classes that match your XML schema and then deserialize your XML into the generated object graph. You can then work with .net types rather than an amorphous XML document with all the compile time type checking, intellisense and other benefits that brings. Xsd.exe comes with Visual Studio, you can easily find it and how to use it by opening the Visual Studio command prompt and typing 'xsd /?'. Serialization and deserialization is handled by the System.Xml.Serialization.XmlSerializer.

The project I'm currently working on requires our piece to communicate with a very complex web service whose WSDL describes more than 380 different types. We initially decided not to deserialize the XML because the serialization process was taking about 7 seconds, an unacceptably long time. Now of course we've dug ourselves into exactly the situation I've described above so I decided to look into the XmlSerializer in a little more depth.

The first thing I did was try and simplify the schema. Although the WSDL's XSD describes those 380 types, the message we actually send only uses a subset, so I've trimmed back the object model to just the types we actually need. It's easy to do, I just commented out the properties that we don't need and since many of these properties are complex types themselves, this often has the benefit of trimming whole branches of the object graph. Doing this I've managed to get the XmlSerialization process down to just under 5 seconds. But 5 seconds is still too long.

The next thing was to do some investigation into where the time was being taken up. I wrote a little test that timed the creation of the serializer and the seralization and deserialization process:

[Test]
public void SerializationTest()
{
	// initialize
    XmlSerializer serializer = null;
    Time("Serializer create", delegate()
    {
        serializer = new XmlSerializer(typeof(MyComplexType));
    });
    
    string inputXmlPath = GetPath(_inputFileName);
    MyComplexType myComplexType = null;

    // deserialize
    Time("Deserialize", delegate()
    {
        using(FileStream stream = new FileStream(inputXmlPath, FileMode.Open, FileAccess.Read))
        {
            myComplexType = (MyComplexType)serializer.Deserialize(stream);
        }
    });

    string outputXmlPath = GetPath(_outputFileName);

    // serialize
    Time("Serialize", delegate()
    {
        using(FileStream stream = new FileStream(outputXmlPath, FileMode.Create, FileAccess.Write))
        {
            serializer.Serialize(myComplexType, stream);
        }
    });
}

private delegate void Function();
private void Time(string description, Function function)
{
    DateTime start = DateTime.Now;
    function();
    DateTime finish = DateTime.Now;
    Console.WriteLine("{0} elapsed: {1}", description, finish - start);
}

The results were as follows:

Serializer create elapsed: 00:00:04.6040060
Deserialize elapsed: 00:00:00.6242720
Serialize elapsed: 00:00:00.1872816

So you can see that the majority of the time is taken by the construction of the serializer itself. What's it doing? I read the docs and did a bit of Googling and found this execellent series of blog posts by Scott Hanselman all about the XmlSerializer.

It turns out that the XmlSerializer emits an assembly that contains a custom serializer for your type when you call it's constructor. If you configure your tests with the following config section:

<configuration>:
  <system.diagnostics>:
    <switches>:
      <add name="XmlSerialization.Compilation" value="1"/>:
    </switches>:
  </system.diagnostics>:
</configuration>:

Then step through the code above and stop after the XmlSerializer contructor is called, you can find the .cs file in your user temp directory (on my machine that's at C:\Documents and Settings\<username>\Local Settings\Temp). You can even load it into Visual Studio, set a breakpoint and debug into it. At first I thought, OK, so I'll just create one serializer and cache it for the lifetime of the application, but after reading Scott's posts I discovered that the XmlSerializer has caching built in. Here's a little test to demonstrate:

[Test]
public void SerializerCachingTest()
{
    XmlSerializer serializer = null;

    for(int i = 0; i < 5; i++)
    {
        Time(string.Format("Creating Serializer {0}", i), delegate()
        {
            serializer = new XmlSerializer(typeof(MyComplexType));
        });
    }
}

Which spits out:

Creating Serializer 0 elapsed: 00:00:05.2907052
Creating Serializer 1 elapsed: 00:00:00
Creating Serializer 2 elapsed: 00:00:00
Creating Serializer 3 elapsed: 00:00:00
Creating Serializer 4 elapsed: 00:00:00

Cached indeed!

The next thing that concerned us was possible contention from multiple threads all trying to use the same cached XmlSerializer concurrently. I wrote a test to kick off ten deserialization requests on ten threads, time them all and time the total elapsed time of the test, here it is:

[Test]
public void ConcurrencyTest()
{
    XmlSerializer serializer = new XmlSerializer(typeof(ProcessUW));
    RunDeserializerHandler deserializerDelegate = new RunDeserializerHandler(RunDeserializer);

    Time("Total", delegate()
    {
        List asyncResults = new List();
        for(int i = 0; i < 10; i++)
        {
            asyncResults.Add(deserializerDelegate.BeginInvoke(serializer, i, null, null));
        }
        foreach(IAsyncResult asyncResult in asyncResults)
        {
            deserializerDelegate.EndInvoke(asyncResult);
        }
    });
}

delegate void RunDeserializerHandler(XmlSerializer serializer, int id);
private void RunDeserializer(XmlSerializer serializer, int id)
{
    string path = GetPath(_inputFileName);

    Time(string.Format("Deserialize {0}", id), delegate()
    {
        using(FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
        {
            MyComplexType myObject = (MyComplexType)serializer.Deserialize(stream);
        }
    });
}

Which gave the following result:

Deserialize 1 elapsed: 00:00:00.9333840
Deserialize 0 elapsed: 00:00:00.9333840
Deserialize 3 elapsed: 00:00:00.3422408
Deserialize 2 elapsed: 00:00:00.8556020
Deserialize 5 elapsed: 00:00:00
Deserialize 6 elapsed: 00:00:00
Deserialize 4 elapsed: 00:00:00
Deserialize 7 elapsed: 00:00:00
Deserialize 8 elapsed: 00:00:00.0155564
Deserialize 9 elapsed: 00:00:00.0155564
Total elapsed: 00:00:00.9644968

Now this is very interesting, not only is the deserialization not contentious (is that the right technical term?) since the total time of the test is only a slightly longer than the longest running individual deserialization, but the XmlSerializer also seems to recognise that it's being asked to do the same thing after the first four attempts and optimises appropriately.

So it after this investigation, it seems that we can use the XmlSerializer in a natural fashion, just constructing it where needed and deserializing / serializing as required. The first time the constructor is called will hit performance, but subsequent uses should be pretty fast. It also looks like the XmlSerializer wont become a bottleneck as our application scales. All in all pretty impressive.

Thursday, November 02, 2006

Using MemoryStream and BinaryFormatter for reuseable GetHashCode and DeepCopy functions

Here's a couple of techniques I learnt a while back to do add two important capabilities to your objects; compute a hash code and execute a deep copy. I can't find the orginal source for the hash code example, but the deep copy comes from Rockford Lhotka's CSLA. Both examples are my implementation of the basic idea. Both techniques utilise the MemoryStream and BinaryFormatter by getting the object to serialize itself to a byte array. To compute the hash code I simply use SHA1CryptoServiceProvider to create a 20 byte hash of the serialized object and get then xor an integer value from that.

public override int public override int GetHashCode()
{
    byte[] thisSerialized;
    using(System.IO.MemoryStream stream = new System.IO.MemoryStream())
    {
        new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Serialize(stream, this);
        thisSerialized = stream.ToArray();
    }
    byte[] hash = new System.Security.Cryptography.SHA1CryptoServiceProvider().ComputeHash(thisSerialized);
    uint hashResult = 0;
    for(int i = 0; i < hash.Length; i++)
    {
        hashResult ^= (uint)(hash[i] << i % 4);
    }
    return (int)hashResult;
}

The most common use for a hash code is to make hash tables efficient and to implement Equals(). Note, there's a one in 4,294,967,295 chance that this will provide a false equals (thanks to Richard for pointing that out to me):

public override bool Equals(object obj)
{
    if(!(obj is MyClass)) return false;
    return this.GetHashCode() == obj.GetHashCode();
}

To do a deep copy I simply get the object to serialize itself and deserialize it as a new instance. Be carefull, this technique will serialize everything in this object's graph so make sure you're aware of what is referenced by it and that all the objects in the graph are marked as [Serializable], Here's a generic example that you can reuse in any object that needs deep copy:

public T DeepCopy<T>()
{
    T snapshot;
    using(System.IO.MemoryStream stream = new System.IO.MemoryStream())
    {
        System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = 
            new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        formatter.Serialize(stream, this);
        stream.Position = 0;
        snapshot = (T)formatter.Deserialize(stream);
    }
    return snapshot;
}

Wednesday, November 01, 2006

Nested files with 'DependentUpon' in Visual Studio

Here's a really neat trick discovered by my colleague Preet that you can use to show a relationship between files in Visual Studio, just like Microsoft does with partial 'designer' classes. You've probably noticed when you add a new windows form in VS 2005 that two files are created: MyForm.cs and MyForm.designer.cs. The designer file contains all the code that's generated by the form designer and the other file is where you write your user code. Preet showed me that you can do the same thing by modifying the .csproj file (aka the MSBuild file) and add a DependentUpon child element to any item that you want to appear below another. Here's a snippet of a .csproj that has three files, all partial classes of 'Foo'. In the solution explorer Foo.1.cs appears nested below Foo.cs and Foo.1.1.cs appears below Foo.1.cs.

  
  <ItemGroup>
    <Compile Include="Foo.1.1.cs">
      <DependentUpon>Foo.1.cs</DependentUpon>
    </Compile>
    <Compile Include="Foo.1.cs">
      <DependentUpon>Foo.cs</DependentUpon>
    </Compile>
    <Compile Include="Foo.cs" />
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>

The only way of doing this at the moment is by editing the .csproj file, but it's pretty cool, especially if you're writing code generators and GAT tools like I have been recently where you might want generated content to be visually related to user written code.

Friday, October 27, 2006

Finally getting around to using NMock

I don't like to admit it, but I really am quite conservative. I get set in my ways and even if I hear about a cool new way to do stuff it often takes me a while to get around to trying it. A great example is NMock. I've known about NMock for probably a couple of years, but I've stubbornly stuck with coding my own mock objects rather than giving it a spin. That is until today when I finally gave in and downloaded NMock2. It's amazing when you think that I've been a champion of TDD in at least three organisations and I've given presentations and mentored people in TDD techniques, but I haven't investigated such a core tool for doing TDD. But then again I only started using Test Driven this year which I couldn't possibly imagine working without now.

NMock is a mock object framework. You use Mock objects and dependency injection in unit tests to allow you to test a single component rather than the whole stack. It's probably one of most important core concepts behind TDD. NMock is a really neat OO framework that leverages the powerfull .net reflection API to create concrete instances of interfaces at runtime. Say you've got an interface like this:

public interface IFoo
{
	int DoSomething(int id, string name);
}

And you've got a client class that uses IFoo to do something:

public class Client
{
	IFoo _foo;

	public Client(IFoo foo)
	{
		_foo = foo;
	}
	
	public int DoSomething(int id, string name)
	{
		return _foo.DoSomething(id, name);
	}
}

You can use NMock to create a mock object like this (I love the name 'Mockery':-):

Mockery mockery = new Mockery();
IFoo mockFoo = mockery.NewMock();

And then set expectations for your unit tests, so that when you run the test, if the correct parameters
aren't passed an exception is raised:

Expect.Once.On(mockFoo).Method("CreatePipelineAudit").With(9, "the name").Will(Return.Value(4));
Client client = new Client(mockFoo);
int result = client.DoSomething(9, "the name");
Assert.AreEqual(4, result);

One thing got me for about half an hour before I was saved by my colleague Preet is that you can't mix bare arguments with 'Is' parameters in the 'Will' clause. In the 'Will' clause you pass the argument values that you expect to be passed to your mock method as I've done above. But also you can use the very convenient 'Is' class that returns a 'Matcher'. What I didn't realise was that 'With' is overloaded:

IMatchSyntax With(params Matcher[] otherArgumentMatchers);
IMatchSyntax With(params object[] equalArgumentValues);

So you can't mix bare values with 'Is' arguments. So this wont work:

Expect.Once.On(mockFoo).Method("CreatePipelineAudit").With(9, Is.Anything).Will(Return.Value(4));

The only other thing that disapointed me about an otherwise excellent tool, is that you can't mock objects, only interfaces. The code I'm currently working on uses several abstract base classes and it would be really neat if NMock could provide mocks for them. I see that it's already a feature request, and that it was available in NMock 1.0. Let's hope they add it soon.

Thursday, October 26, 2006

More than just code?

Jeff Atwood's Coding Horror is one of my favorite blogs. One of his recent posts argued that most of us are so involved with the detail of our applications that we don't step back enough and ask why we're writing a specific piece of software. He suggests that we should become business people and lawyers and concentrate less on coding, or maybe even stop coding all together. Sure what's the point in writing great code if it never ships or nobody ever knows about it. I often read good arguments that coders should become better writers, salesmen or business people, but the problem with that argument is that it misses two important points:

First is that often the reason people become coders is because they are much stronger dealing with abstract ideas than with other humans. It's widely noted that often the best coders are boderline autistic and in a way it's great that there is such a job as 'programmer' that means lots of these people can earn a good living without having too much painfull interaction with other humans:)

Secondly is the complexity of modern society that demands deep specialisation. There's simply too much knowledge out there for anyone to be a renaisance man in the 21st century. I have enough trouble just keeping up with what's going on in the world of .net development, let alone other languages and platforms. There's simply no way that I've got enough mental bandwidth to be a great lawyer or salesman too. So sure it's good to be at least dimly aware of the reason why you're writing that code, but I expect for the vast majority of corporate developers, the reason they're writing that code is because their boss told them to.

Now, if are one of those exceptional people that do have the mental bandwidth to be a great lawyer salesman and programmer, then you'll probably end up being very successfull anyway. One reads stories of Bill Gates out legalling (is that a word?) his lawyers and he's obviously a great salesman too, but I think for most of us lumpen programmeren just keeping up with our corner of the coding world is probably work enough.

Monday, October 23, 2006

Playing with Providers

'Inversion of control' (also known as 'dependency injection' or the 'dependency inversion principle') is a common OO pattern that allows you to decouple the layers of your application by removing the dependency of client class on a server class. It is not only good practice, but essential for writing unit tests. Rather than hard coding the server's concrete type in the client, you make the client refer to a server interface or abstract class and inject the concrete server at runtime. Sometimes you'll have the server injected by a co-ordinator or service class, but in many cases you want to be able to configure the server so that you can change the server's type without having to recompile the application. This becomes essential if you're writing a reusable framework where you want to allow your users to provide their own servers and indeed, the .NET base class library uses this pattern extensively. In previous versions of .NET you had to roll your own code to read the type information from a config file and then load the correct assembly and instantiate the correct type, but now in .NET 2.0 there's a Providers framework that makes it child's play to load in servers at runtime. The classes live in the System.Configuration.Provider namespace.

OK, my client uses this interface with a single method 'DoIt()':

public interface IServer
{
	void DoIt();
}

I have to define a base provider that implements this interface and extends System.Configuration.Provider.ProviderBase:

public abstract class ServerProvider : ProviderBase, IServer
{
	public abstract void DoIt();
}

I also need a custom configuration section to place my providers in. Note that we need to provide a 'DefaultProvider' property and a 'Providers' property. The DefaultProvider tells us which provider we should use, but allows us to keep multiple providers on hand if we, for example, want to allow the user to select from them at runtime. The Providers property is of type ProviderSettingsCollection that's supplied for us in the System.Configuration namespace. The new custom configuration section feature of .NET 2.0 is also really nice, but that's another post...

public class CustomConfigSection : ConfigurationSection
{
	[ConfigurationProperty("DefaultProvider")]
	public string DefaultProvider
	{
		get { return (string)this["DefaultProvider"]; }
	}

	[ConfigurationProperty("Providers")]
	public ProviderSettingsCollection Providers
	{
		get{ return (ProviderSettingsCollection)this["Providers"]; }
	}
}

Now, in our client we just grab our custom config section and use the System.Web.Configuration.ProvidersHelper class to load our providers, it's that easy. You can then just select the default provider or maybe provide a list for the user to select. I've left out all the error handling code to make it simpler, but you really should check that the stuff gets loaded that you're expecting

Configuration configuration = ConfigurationManager.OpenExeConfiguration(
    ConfigurationUserLevel.None);
CustomConfigSection section = configuration.Sections["CustomConfigSection"] as CustomConfigSection;
ProviderCollection providers = new ProviderCollection();
ProvidersHelper.InstantiateProviders(section.Providers, providers, typeof(ServerProvider));
ServerProvider provider = (ServerProvider)providers[section.DefaultProvider];
...
provider.DoIt();

Here's a sample provider called XmlServerProvider. Note the Initialize method that you have to implement. It takes the name of the provider and a name value collection 'config' that contains any properties that you might require to be set for your provider. In this case, apart from the common name and description properties, the provider also requires a 'filePath' property. You should also check that there aren't any superfluous properties in the configuration.

public class XmlServerProvider : ServerProvider
{
	string _filePath;

	public override void DoIt()
	{
		....
	}
	
	public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
    {
        if(config == null) throw new ArgumentNullException("config");
        if(string.IsNullOrEmpty(name))
        {
            name = "XmlServerProvider";
        }
        if(string.IsNullOrEmpty(config["description"]))
        {
            config.Remove("description");
            config.Add("description", "A xml based server");
        }
        base.Initialize(name, config);

        // test that each property exists
        _filePath = config["filePath"];
        if(string.IsNullOrEmpty(_filePath))
        {
            throw new ProviderException("filePath not found");
        }

        // throw an exception if any unexpected properties are present
        config.Remove("filePath");
        if(config.Count > 0)
        {
            string propertyName = config.GetKey(0);
            if(!string.IsNullOrEmpty(propertyName))
            {
                throw new ProviderException(string.Format("{0} unrecognised attribute: '{1}'",
                    Name, propertyName));
            }
        }
    }	
}

And last of all, here's a snippet from the App.config or Web.config file. You have to define your custom config section in the configSections section. Here we're loading the XmlServerProvider, note the name, type and filePath properties.

<configSections>
<section name="CustomConfigSection" type="MyAssembly.CustomConfigSection, MyAssembly" />
</configSections>
<Operation DefaultProvider="XmlServerProvider">
<Providers>
<add
name="XmlServerProvider"
type="MyAssembly.XmlServerProvider, MyAssembly"
filePath="c:/temp/myXmlFile.xml" />
</Providers>
</Operation>

Thursday, October 19, 2006

What is AzMan?

Does your application require a finer grained level of control than simply authorizing users to access a particular web directory or windows form? Do you have complex roles with overlapping tasks that consist of multiple operations? Do you want to be able to disable or enable individual user interface elements according to the user's role definitions? Are your roles complex and likely to change during the operational life span of your application?

The .net framework has a nice API for managing role based security which works on a simple but effective mapping of users to roles:

[User] -- has a --> [Role]

But with complex business requirements where different roles have overlapping tasks within the application and you need to be able to modify roles without recompling, it's often neccessary to have a more complex model that maps operations (individual functions within the application like 'Add order line' for example) to tasks (like 'Order product for user') and tasks to roles (like 'Sales advisor'):

[User] -- has a --> [Role] -- is allowed to execute --> [Tasks] -- are made up of --> [Operations]

This means that the application can simply ask if a given user has permission to execute a certain operation and it can be left to an administration function, with a nice GUI, to assign the operations to tasks and the tasks to roles rather than baking it into the application code.

It's quite common for people to spin their own security sub systems that have this more complex model. I've seen some pretty involved home made security frameworks out in the wild and it creates a considerable development overhead. What's needed is a built-in API for managing this more complex authorization model.

AzMan is a COM based API for managing application security that originally shipped with Windows Server 2003, but is now also available for XP (with the Windows Server 2003 Administration Tools Pack). It allows you to define fine grained operations that can be grouped into tasks that can in turn be assigned to roles as I explained above. The backing store can be either a xml file or Active Directory (can also use ADAM a stand alone Active Directory that can be created for individual applications). AzMan also adds a nice GUI MMC plugin for user/group/role management.

Unfortunately it's a COM based API and as yet it's not supplied with a convenient wrapper, you have to use the interop and there's a good MSDN article here on how to do that (Use Role-Based Security in Your Middle Tier .NET Apps with Authorization Manager).

AzMan can also be used without any extra coding in the ASP.NET 2.0 security model, but since that model is role based you can't leverage any of the operation based features, for that you need to write to the Interop API. To use AzMan in ASP.NET 2.0 simply configure your authorization role provider as the AuthorizationStoreRoleProvider class that's a supplied with the framework (How To: Use Authorization Manager (AzMan) with ASP.NET 2.0)

Wednesday, October 11, 2006

log4net

Today I've been playing with a logging framework called log4net. It's a port of a java logging framework (log4j would you believe), that's really popular. The nice thing about log4net is that it's really simple to use and configure and comes with a huge range of log sinks (known as 'appenders' in log4net speak) straight out of the box, you can even log to telnet. I think the sign of a good framework is one that lets you get up and running really quickly without having to study the full model, but has the extensibility to allow you to do the more complex stuff if you need to as well as being fully configurable without having to recompile you application and log4net seems to be that kind of framework. I haven't used the logging application block from the P&P group, so I can't compare it to that. For me, moving up from writing directly to a file or the event log is a big move forward.

Friday, October 06, 2006

No to #region!

The #region directive in C# was invented so that a code file can be split up into collapsable regions to aid navigation. I can stand them, and here's my list of region irritations...

  1. They're like comments, they don't execute so it's easy to have regions which tell you something completely wrong. How about the region '#region public properties' that contains nothing but private methods. Yeah, I've seen that enough. Martin Fowler in his excellent book Refactoring says "When you feel the need to write a comment, first try to refactor the code so that any comment becomes superfluous". The same goes for regions, if you feel a region comming on, maybe you need to refactor, which brings me to...
  2. If you're code file is so large that it needs regions to keep it organised, maybe your code file is too large. Visual Studio likes to have one class per file and classes shouldn't be so large that they need to be split into regions. Maybe when you feel a region comming on you should try refactoring your class into more smaller classes. What about regions that split up a method into easier to understand segments? You have regions inside methods???? That's too far gone!
  3. What's wrong with the great tools that come with Visual Studio for helping you navigate around your code. I think one look at the Class View is worth a million stupid regions and if what you see in the class view doesn't make any sense then you should really get a copy of 'Refactoring'. Well named methods and classes in a well designed object model should make your code easy to understand and navigate.

So just say no to regions, I'm sick of clicking on those stupid little + signs!