Browsing Posts published in 2006

My MSDN Magazine article entitled Debug Leaky Apps: Identify and Prevent Memory Leaks in Managed Code has been published in the January 2007 issue. Go check it out!

Due to space constraints, the editors at MSDN Magazine left a few acknowledgements on the cutting room floor. I would like to acknowledge Rico Mariani (MS) for coining the term “midlife crisis” as it applies to the garbage collector. His blog is full of excellent perf advice and insight. I would also like to acknowledge Tess Ferrandez (MS) as one of the examples in the article is based on her blog post, “Does Page.Cache leak memory?“.

Finally, a very special thanks to my spouse, Risa Kawchuk, for her patience and excellent editing of the many versions of the manuscript.

There are many paths to software enlightenment, to attaining the state of development nirvana knows as ZenBoo. Masters of the art of ZenBoo can invert dependencies at will, value coding to interface* not implementation, favour composition over inheritance,** and respect the open-closed principle.***

On your journey to becoming a ZenBoodist, you will encounter many revelations and wonders. While meditating on test-driven development (TDD), you will gain deeper understanding of the technique. First you will realize the power of an automated test harness and a suite of regression tests that prevent bugs from finding their way into your code base. Next you will realize that your suite of unit tests allows you to confidently refactor your code base. Finally you will discover the power of mocking and realize that TDD is not a testing technique, but an agile design technique. Other wonders abound including better layered architectures, O/R mapping, IoC containers, and more.

How can I achieve a state of ZenBoo, you might ask? Everyone’s path is different, but I offer you a few humble suggestions. You must first understand object-oriented design. Just understanding object-oriented programming isn’t enough. You have to know how to design object-oriented hierarchies through responsibility assignment. Which object/class is responsible for X? By assigning responsibility for X to this object/class, how does that affect my coupling, cohesion, and a myriad of other factors? A good treatise on the subject is Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd Edition) by Craig Larman.

By understanding responsibility assignment, software patterns suddenly make sense. You have a framework upon which to understand patterns and upon which to build new ones. Everyone should read Head First Design Patterns (Head First) by Eric Freeman and Elizabeth Freeman. This book offers deep insight into the ZenBoodist mind in a playful, approachable way. Although it is written for Java developers, it is equally applicable to and comprehensible by C# developers. It covers the classic “Gang of Four” software patterns, but frames them in within actual problems so that you can see how to apply them. You understand the power of coding to interface not implementation, why we favour composition over inheritance, and how to apply the open-closed principle. If you’re going to read one software book in the next year, this should be it.

Now that you understand the “Gang of Four” patterns and the basic ZenBoodist philosophies, it is time to understand how to design real-world architectures and build real-world applications. For this, we turn to Applying Domain-Driven Design and Patterns: With Examples in C# and .NET by Jimmy Nilsson. He blends together elements of Eric Evans’ Domain-Driven Design and Martin Fowler’s Patterns of Enterprise Application Architecture to take you on a journey of discovery through TDD, mocking, O/R mappers, domain-driven design, and more.

Becoming a ZenBoodist master is a difficult journey, but one well worth it. Once you achieve development nirvana, you will code with elegance, refactor with confidence, and dream in patterns. You will also realize that you are but a humble grasshopper wanting to learn more.

<plug type=”shameless” subject=”http://www.jpboodhoo.com”>

If you want to get a jumpstart on ZenBoodism, check out Jean-Paul Boodhoo‘s Nothin’ but .NET course. You get 5 days of top-notch training from a ZenBoodist master, a ReSharper 2.0 license, Martin Fowler’s Patterns of Enterprise Application Architecture, and free food. The next course is in Edmonton on February 19-23, 2007. Highly recommended.

</plug>

<shelf type=”reference”>

The following reference books are useful to have on your shelf, but you probably don’t want to read them cover-to-cover unless you’re crazy. (Yes, I’ve read all of these cover-to-cover and thoroughly enjoyed them.)

</shelf>

<footnotes>

* Interface in this context can mean abstract base class or interface. The point is not to depend on a specific type, but on a contract definition.

** Favouring composition over inheritance does not mean abandoning inheritance. True ZenBoodists combine the powers of inheritance with composition to make truly powerful object models. While inheritance is over-used, don’t under-use it either.

*** Open-closed principle: Classes should be open for extension, but closed for modification.

</footnotes>

Full Disclosure: The book links above are through the Amazon Affiliates program. If you buy a book through that link, I get more books from Amazon to sate my hunger for knowledge.

This post by S. Somasegar, VP of Microsoft’s Developer Division, stirred up quite a racket back in September about incompatibilities in VS2005 on Windows Vista. Now that I’ve had a chance to use VS2005 on Vista seriously for a few weeks, I can say that it’s much ado about nothing. VS2005 is a complex application. Does it run on Vista? Yes. Does it run as a limited user or a filtered administrator*? Yes. Are there problems? Yes. Are they show-stoppers? Not for the most part. Full details, including broken features, can be found here on MSDN. If you’re depending on one of these features, life sucks. For most developers, it will mean the occasional visual glitch. I’ve had this happen once and a simple refresh of the Visual Studio window resolved it.

In a way, I can understand where the DevDiv is coming from. VS2005 is in the support channel now and they’re actively working on “Orcas” or Visual Studio vNext. Orcas is the development tool designed to target Vista and .NET 3.0. You’ll notice that all the .NET 3.0 designers are CTPs. They’re works in progress and destined for Orcas as their final home. (I don’t know if VS2005-compatible versions will also be available.) The unfortunate part is that the most likely early adopters of Vista are developers and the DevDiv doesn’t have a fully-supported tool for the platform. Now that sucks. Microsoft has built mind-share by creating a fantastic platform for developers. Developers are a bit out in the cold when it comes to Vista and .NET 3.0. Imagine releasing .NET 2.0 without VS2005? On the one hand, Microsoft should have coordinated th release of Orcas with Vista. On the other hand, by the time most developers will be looking at Vista, Orcas will be released. It’s only us early adopters that need to brave the excitement of running an unsupported developer tool on the latest version of Microsoft’s flagship OS. Honestly, it’s not all that exciting. For the most part, VS2005 works as it always has with a few rough edges due to UAC.

* A filtered administrator is an administrator whose admin token has had most of its privileges stripped out and the Administrators’ group SID changed to a deny. The real admin token is kept in waiting, heavily protected, and is activated when the user clicks “Continue” on a UAC prompt. A good review of the details can be found here on Márton Anka’s weblog. He also has some good information on how to declaratively and programmatically request an elevation of privilege. (i.e. Throw up the UAC prompt.)

When you try to install SQL Server 2005 Reporting Services on Windows Vista, the installer apparently fails to recognize that IIS7 is installed (assuming that you have installed it). The error message is misleading and is due to the fact that IIS7 components required by Reporting Services are not installed. IIS7 has been much more componentized than IIS6 and there is a magical list of IIS7 features that must be installed in order for Reporting Services to install successfully. The required IIS7 features are documented in KB article 920201.

Component Folder
Static Content Common HTTP Features
Default Document Common HTTP Features
HTTP Redirection Common HTTP Features
Directory Browsing Common HTTP Features
ASP.Net Application Development
ISAPI Extension Application Development
ISAPI Filters Application Development
Windows Authentication Security
IIS Metabase Management Tools
IIS 6 WMI Management Tools

Once you have SQL Server installed, you will need to install SQL Server 2005 SP2 November 2006 CTP or later as it addresses some Vista-compatibility issues. You can find the latest SQL Server 2005 service pack information here. You should now have a working Reporting Services install on Vista.

On a recent project, I was trying to return an object (with child objects) from an ASMX Web Service and was using the XmlSerializer for serialization. (When doing ASMX Web Services, you really have no choice but to use the XmlSerializer.) The child objects contained a circular reference, which ended up being the bane of my existence because the XmlSerializer can’t handle circular references. The XmlSerializer reports, “Circular reference detected” and gives up. It just can’t serialize it. The amount of code (and changes to the domain model) to work around this limitation was just plain stupid, not to mention the subtle bugs that needed to be fixed when object identity wasn’t respected in other areas of the object graph.

So what does this have to do with Windows Communication Foundation (WCF)? Given how excited I’ve been about WCF, my fellow developers (and the PM) asked if WCF would have avoided the XmlSerializer problems that we had experienced. My curiosity was piqued and I had to find out. As it turns out, WCF can handle circular references and preserve object identity. Or more correctly, the DataContractSerializer can. This would have saved me untold effort if I had been able to use WCF on the project. (Unfortunately release dates didn’t match up. Ironically the project released into production the day before WCF went RTM.) Just a pronouncement that WCF can handle circular references wouldn’t make for a very interesting blog entry. The reality is that out-of-the-box, WCF cannot handle circular references even though the DataContractSerializer can. With a bit of digging, I was able to configure WCF to serialize circular references and properly preserve object identity.

Let’s take a deeper look… Consider a simple object graph with a circular reference. The simplest is a parent-child relationship where the child has a back-reference to the parent. (My situation was more complex, but this example suffices.) Here is a Person class, which has a list of Children, as well as a reference to its parent.

[DataContract(Namespace="http://jameskovacs.com/Examples/WcfCircularRefs")]

public class PersonDTO {

    [DataMember]

    public string Name {

        get { return m_name; }

        set { m_name = value; }

    }

 

    private string m_name;

    [DataMember(Name="Parent")]

    private Person m_parent;

    [DataMember(Name = "Children")]

    private List<Person> m_children = new List<Person>();

 

    /* Additional constructors/properties/methods elided. */
    /* I’ve also omitted the Order and IsRequired DataMember parameters above. */

    /* Full source can be found in the linked zip file at the end. */

}

<Aside>One of the nice things about the DataContractSerializer is that serialized members are opt-in. If you don’t decorate a member with the [DataMember] attribute, it is not serialized. For instance, m_name is not decorated and is therefore ignored by the DataContractSerializer. This is in stark contrast to the XmlSerializer where all public read/write properties are serialized unless they are marked with [XmlIgnore]. Another point to note is that I can serialize both properties and fields, which allows me to have read-only properties, such as m_parent and m_children, while still serializing them at the field level. (N.B. You can still configure WCF to use the XmlSerializer for compatibility, though the preferred serializer is the DataContractSerializer.)</Aside>

Now why can’t WCF handle circular references out-of-the-box. The reason is that there is no industry-accepted, interoperable way of expressing anything but parent-child relationships in XML. You can use the ID/IDREF feature of XML or the key/keyref feature of XML Schema, but a lot of serializers don’t respect these attributes or handle them properly. So if you want to serialize circular references, you need to stray out of the realm of safe interoperability. I found some very intriguing information in Aaron Skonnard’s MSDN article about the DataContractSerializer, Serialization in Windows Communication Foundation. When instantiating the DataContractSerializer, you can tell it to respect object identity (and thus handle circular references) by passing true for preserveObjectReferences constructor parameter.

DataContractSerializer serializer = new DataContractSerializer(typeof(PersonDTO), null, int.MaxValue, false, true /* preserveObjectReferences */, null);

serializer.WriteObject(memStream, person);

The resulting XML looks like this:

<PersonDTO z:Id=1 xmlns=http://jameskovacs.com/Examples/WcfCircularRefs xmlns:i=http://www.w3.org/2001/XMLSchema-instance xmlns:z=http://schemas.microsoft.com/2003/10/Serialization/>

    <Name z:Id=2>Sam Spade</Name>

    <Parent z:Id=3>

        <Name z:Id=4>Unknown</Name>

        <Parent i:nil=true/>

        <Children z:Id=5 z:Size=0/>

    </Parent>

    <Children z:Id=6 z:Size=2>

        <PersonDTO z:Id=7>

            <Name z:Id=8>Jane Spade</Name>

            <Parent z:Ref=1 i:nil=true/>

            <Children z:Id=9 z:Size=0/>

        </PersonDTO>

        <PersonDTO z:Id=10>

            <Name z:Id=11>Bobby Spoon</Name>

            <Parent z:Ref=1 i:nil=true/>

            <Children z:Id=12 z:Size=0/>

        </PersonDTO>

    </Children>

</PersonDTO>

You’ll notice that references to other objects are encoded using the z:Id attribute. So the DataContractSerializer can handle circular references, but how do we tell WCF to pass true for the preserveObjectReferences parameter when creating a DataContractSerializer? We can’t, but what we can do is do it ourselves and wedge our code into the WCF pipeline. Is that cool or what? All the details can be found in Ingo Rammer’s MSDN Library Article, From .NET Remoting to the Windows Communication Foundation (WCF). We create a class derived from DataContractSerializerOperationBehaviour, which we’ll call PreserveReferencesOperationBehavior. Here’s the important overload:

public override XmlObjectSerializer CreateSerializer(

  Type type, XmlDictionaryString name, XmlDictionaryString ns,

  IList<Type> knownTypes) {

    return new DataContractSerializer(type, name, ns, knownTypes,

        0x7FFF,

        false,

        true /* preserveObjectReferences */,

        null);

}

So we’ve wedged in the preserveObjectReferences = true. We then create an attribute, PreserveReferencesAttribute, which implements IOperationBehavior, to inject the PreserveReferencesOperationBehavior.

public void ApplyDispatchBehavior(OperationDescription description,

  DispatchOperation dispatch) {

    IOperationBehavior innerBehavior =

      new PreserveReferencesOperationBehavior(description);

    innerBehavior.ApplyDispatchBehavior(description, dispatch);

}

Finally, we apply this attribute to the OperationContract in our ServiceContract.

[ServiceContract(Namespace="http://jameskovacs.com/Examples/WcfCircularRefs")]

public interface IPersonService {

    [OperationContract]

    [PreserveReferences]

    PersonDTO GetDefaultPerson();

}

Our service is now able to serialize circular references, as well as preserve object identity. If we need to transmit objects with circular references back to the service, we could make similar changes to inject PreserveReferencesOperationBehavior into the client-side proxy.

To summarize, WCF is a very extensible framework for distributed communication. We were able to make some small modifications to the WCF pipeline that allowed us to return an object graph with circular references from a service. With the release of WCF, the life of the distributed application developer just got a whole lot easier. Full source code can be found here (16 KB).

N.B. The HTTP transport in WCF relies on http.sys for hosting HTTP ports outside of IIS. Opening up arbitrary HTTP ports cannot be done by non-admins unless they have been granted permission by an administrator. This means an administrator must run httpcfg to grant non-admin users permission to open these ports.

The .NET Framework 3.0, formerly known as WinFx, has gone gold. You can download the release bits now. Congrats to everyone involved in this release!

If you have a previous version installed (CTP or Beta), you’ll want to read the uninstall instructions found below the download link for the uninstall tool. (The uninstall tool is there in case Add/Remove Programs fails in a horrible way.)

I am now a card-carrying member of the MSDN Canada Speakers Bureau*. (OK, maybe they don’t issue cards, but it’s still a great honour.) The long and short of it is that user groups from across Canada can invite me to speak and Microsoft Canada will cover the expenses.

Here are some possible topics:

  • Enterprise Architecture for Mere Mortals: Authentication
    • Discussing advantages/disadvantages of different authentication models and how to make them work, including trusted subsystem, full delegation, constrained delegation, and protocol transition.
  • Tools of the Trade: Must-Have .NET Utilities
    • An overview of .NET tools that should be in your toolbox.
  • ASP.NET Kung-Fu: Advanced Techniques and Idioms
    • Solving problems in ASP.NET using techniques such as HttpHandlers and HttpModules.
  • Introducing Windows CardSpace
    • Looking at the technology, its architecture, and why you should care.

I’ll be adding more presentations in the coming months. So if you are looking for someone to present on a particular topic, don’t hesitate to ask. I might have something in my back pocket…

* Please note that the public page is horribly out-of-date. Some people have incorrect information. Others, such as Jean-Paul Boodhoo, are not yet listed. User Group leaders have up-to-date information on all speakers. Talk to them about inviting one of us to come speak at your user group.

BTW – If you’re looking for a fantastic presenter to talk about TDD, Agile, and patterns, I would highly recommend inviting Jean-Paul out to your user group.

A few months ago, Joanne Cummings of Redmond Magazine interviewed me regarding my thoughts on Microsoft Virtual PC and how it compares to VMWare Workstation. The article was recently published and you can find it here. Joanne did a good job capturing my thoughts on the overall advantages and disadvantages of the two products. While I’m overall quite favourable toward Microsoft software (I honestly think Microsoft does a good job in most cases and a great job in many), desktop-based virtualization is one area where they fall short. Read the article to find out more. Thanks, Joanne, for the opportunity to share my thoughts on VPC and VMWare.

Show Notes

I must bid a fond farewell to a fellow plumber, Dan Sellers. Today was Dan’s last day in the Big House. He is stepping into a well-deserved, early retirement. Dan and I have worked together many times over the years especially on Plumbers @ Work and more recently on the Canadian Developer Security Virtual Team. (I’ve got some posts and content coming up soon.) The developer scene in Canada will not be the same without him. Congratulations, Dan. You’ll be missed.