Want to show your appreciation? Please to my charity.

Friday, December 04, 2009

Class Diagram For Major Collection Interfaces in .Net

Today, I want to show somebody a class diagram for major collection interfaces in .Net. I created one after failed Googling one. So here it is.

CollectionInterfaces

And below for enumerators. I hope I can show “has a” relationship but VS 2008 doesn’t let me do it. So I placed them side by side to show enumerable has enumerator.

EnumeratorInterfaces

Wednesday, November 04, 2009

Unit Test Value Object – Reusable Test Fixture

To Test Or Not Test

Shall I unit test value object? Here are some arguments that I found when googling for an answer to the question.

  1. Value object are so simple that you don’t need to test them.
  2. Test value object is tedious, basically copy and pasting and you can make the same mistake that you did in the value object itself.
  3. If you test every other part of the application, you would have tested your value object.

And there are also opposite opinions.

  1. Value objects are not as simple as you thought. How about initial property value, equals, hashcode and cloneable? (Yes, that reminds me that I made quite some mistakes in value objects)
  2. Unit test is tedious in nature. Tedious is not a reason for not doing it. But it only means that we need to find a better way.
  3. This is about unit testing, not integration testing. Value object is a unit that should be tested alone.

In summary, value objects are relatively simple so that the cost of manually writing test cases for them are too high to justify the benefit but not testing them leaving potential bugs.

The Reusable Test Fixture

Compromising the quality is a no in my book so the solution is to develop reusable tests to replace the repetitive and tedious work. This is what programmers are good at after all!

Let’s take a look at a very simple value object.

public class Foo
{
    public int Id { get; set; }
 
    public string StringProperty { get; set; }
 
    public long LongProperty { get; set; }
}

Writing a unit test for this class manually is plain boring. I should be able just do it in one line with a reusable test fixture.

[TestFixture] public void FooTest : SomeMagicReusableTestFixture<Foo> {}

This magic reusable test fixture is called NewableValueObjectTestFixture. It sets each property with a few (three minimal) values and read it back to make sure it gets the same value previously set. Of course, it does much more then just that…

Default Property Value

The above example is probably too simple. What if my property has default value? say the Id property is initialized to –1. No problem! The reusable test fixture also verifies the initial value of properties too. It expects all the properties are initialized to the default value of the type, or a value specified by DefaultValueAttribute.

The code below will fail the test because the the default value for int type is 0, not –1.

    private int _id = -1;
 
    public int Id
    {
        get { return _id; }
        set { _id = value; }
    }

If you intended to initialized to –1, you should tell this to the test fixture. The information is also useful to other .Net tools.

    private int _id = -1;
 
    [DefaultValue(-1)]
    public int Id
    {
        get { return _id; }
        set { _id = value; }
    }

The code above passes the test happily.

Equals and GetHashCode

NewableValueObjectTestFixture and its brother ValueObjectTestFixture test the Equals and GetHashCode methods too. They basically ensure that:

  1. The value object does not equals to null.
  2. The value object does not equals an arbitrary object (new object()).
  3. The value object equals to itself.
  4. The value objects are not equal if any one of their properties are not equal.
  5. When two value objects have same property values and Equals method returns true. The GetHashCode methods must return same value.

The implementation in the Object class complies to the above rules so the your value object passes the tests by default. But if you decide to override any of them, the test helps to ensure you have implemented Equals and GetHashCode properly, otherwise the test will fail. Below is generated by Resharper and it passes the test.

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != typeof(Foo)) return false;
        return Equals((Foo)obj);
    }
 
    public bool Equals(Foo other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return other._id == _id &&
            Equals(other.StringProperty, StringProperty) &&
            other.LongProperty == LongProperty;
    }
 
    public override int GetHashCode()
    {
        unchecked
        {
            int result = _id;
            result = (result * 397) ^ (StringProperty != null ? StringProperty.GetHashCode() : 0);
            result = (result * 397) ^ LongProperty.GetHashCode();
            return result;
        }
    }

A few days later if I add another property to the Foo class and forget to added it to the Equals method, the test fixture will effectively catch it and fails the test. This is exactly what I wanted, how many times did I forget this?

Cloneable

If my value object implements ICloneable, the test fixture will help to check that as well. It clones the object and test all readable properties to make sure the cloned one has the same property values. Below is my typical clone implementation and it works well with the test fixture.

public class Foo : ICloneable
{
    public int Id { get; set; }
 
    public string StringProperty { get; set; }
 
    public long LongProperty { get; set; }
 
    object ICloneable.Clone()
    {
        return Clone();
    }
 
    public Foo Clone()
    {
        return (Foo)MemberwiseClone();
    }
}

Type of Property

Since the test fixture needs to generate test data, it had limited support for the type of the properties. For example, a property of interface type would be difficult for ValueObjectTestFixture to create test data of it.

Although, out of the box, ValueObjectTestFixture only support properties of c# build-in data types plus DateTime and TimeSpan, but it provides two extension mechanisms. You can either use a mock framework to generate mock objects for interface type and class type, or override the TestData method to provide your own test data for types that are not supported by the default implementation. Of course, nothing prevents you from making mixed use of both mechanisms.

Future enhancement may have ValueObjectTestFixture support enum, concrete class and/or maybe struct.

Using Mock Framework to Generate Test Data

ValueObjectTestFixture accepts an IMockTestDataProvider instance. I have included an implementation using RhinoMocks. But you can easily do the same using any other mock frameworks. RhinoMockTestDataProvider mocks any interfaces, or classes that are not sealed and has a default constructor. We may be able to remove the requirement of a default constructor in future but for now that is it. :)

Take a look at below value object:

public class ValueObject
{
    public IList<string> StringIList { get; set; }
 
    public List<TimeSpan> TimeSpanList { get; set; }
 
    public ICollection<int> IntICollection { get; set; }
 
    public IDictionary<string, object> StringObjectIDictrionary { get; set; }
 
    public Dictionary<int, DateTime> IntDataTimeDictionary { get; set; }
 
    public Component Component { get; set; }
 
    // other properties, equals, hash code, clone and etc.
}

To test this, the test class is as simple as below:

    [TestFixture]
    public class MockProviderTest : NewableValueObjectTestFixture<ValueObject>
    {
        public MockProviderTest()
        {
            MockProvider = new RhinoMockTestDataProvider();
        }
    }

The complete example can be found in Google code: MockProviderTest.cs

Provide Your Own Test Data

If you have property type that is neither supported out-of-box, nor by a mock framework. You can always provide it yourself by overriding the method TestData. Below is an example from CustomTest.cs:

        protected override IEnumerable TestData(PropertyInfo property)
        {
            // ValueObjectTestFixture doesn't support enum at this moment
            // so we have to provide our own test data.
            if (property.PropertyType == typeof(Operation))
            {
                return new[]
                           {
                               Operation.Subtraction, 
                               new Operation(), 
                               Operation.Addition, 
                               Operation.Muiplication, 
                               Operation.Division
                           };
            }
            return base.TestData(property);
        }

Extensibility

While ValueObjectTestFixture makes simple things simpler, it ensures complex things possible too. Here are some additional features that will come handy when testing not so simple value objects.

Value Object without Default Constructor

What if the value object doesn’t have a default constructor? No problem, have the test case inherit from ValueObjectTestFixture. The only difference between ValueObjectTestFixture and NewableValueObjectTestFixture is that the former forces you to override an abstract method: NewValueObject, which you are required to return a new instance of the value object under test. Below example is from CustomTest.cs:

        protected override CustomObject NewValueObject()
        {
            return new CustomObject("TestObject");
        }

Test Special Properties Myself

There are times that value object has non-simple properties. For example, when a read only property is initialized by the constructor:

public class CustomObject
{
    private readonly string _name;
    public CustomObject(string name)
    {
        _name = name;
    }
 
    public string Name { get { return _name; } }
}

Or, when a property is calculated from others:

public int Result
{
    get
    {
        switch (Operation)
        {
            case Operation.Addition:
                return LeftOperand + RightOperand;
            case Operation.Subtraction:
                return LeftOperand - RightOperand;
            case Operation.Muiplication:
                return LeftOperand * RightOperand;
            case Operation.Division:
                return LeftOperand / RightOperand;
            default:
                throw new InvalidOperationException("Unsupported operation " + Operation);
        }
    }
}

ValueObjectTestFixture provides two ways to exclude those properties from being tested by it. But then you need to write the test cases yourself.

One way is to use one of the ExcludeProperties methods. Typically you call it in the constructor of your test fixture. Below is from CustomText.cs:

    [TestFixture]
    public class CustomTest : ValueObjectTestFixture<CustomTest.CustomObject>
    {
        public CustomTest()
        {
            // Exclude the Name property from being tested by ValueObjectTestFixture.
            ExcludeProperties("Name");
        }
        // ... ...
    }

This completely excludes the property from all the tests administered by ValueObjectTestFixture.

Another less aggressive approach is to override one of the XyzCandidates methods. They are listed below to provide a custom list of properties for the corresponding tests:

Example from CustomText.cs:

        public override IEnumerable<PropertyInfo> EqualsTestCandidates()
        {
            // Exclude the Tag property from equality test.
            return from p in base.EqualsTestCandidates() where p.Name != "Tag" select p;
        }

You opinions is important. Let me know what you think :)

Monday, October 26, 2009

Generating Interface, Typical Implementation and Decorator of Value Objects

Things To Be Generated

In one of design session, we all felt being repeatedly writing interface, implementation and decorator class for simple value objects that we use. Let’s say way have interfaces below:

    public interface IBase
    {
        IPartOne PartOne { get; set; }
        int BaseInt { get; set; }
        string BaseString { get; set; }
    }
 
    public interface IPartOne
    {
        int PartOneInt { get; set; }
        string PartOneString { get; set; }
    }
 
    public interface ISub : IBase
    {
        int SubInt { get; set; }
        string SubString { get; set; }
 
        IPartTwo PartTwo { get; set; }
    }
 
    public interface IPartTwo
    {
        int PartTwoInt { get; set; }
        string PartTwoString { get; set; }
    }

And then we write implementations

    public class Base : IBase
    {
        public IPartOne PartOne { get; set; }
        public int BaseInt { get; set; }
        public string BaseString { get; set; }
    }
 
    public class PartOne : IPartOne
    {
        public int PartOneInt { get; set; }
        public string PartOneString { get; set; }
    }
 
    public class PartTwo : IPartTwo
    {
        public int PartTwoInt { get; set; }
        public string PartTwoString { get; set; }
    }
 
    public class Sub : Base, ISub
    {
        public int SubInt { get; set; }
        public string SubString { get; set; }
        public IPartTwo PartTwo { get; set; }
    }

And then we wrote decorators so that it can be XML serialized:

    public class BaseDeco : IBase
    {
        private readonly IBase _base;
 
        public IBase Base
        {
            get { return _base;}
        }
 
        public BaseDeco() : this(new Base()) 
        {
        }
 
        public BaseDeco(IBase @base)
        {
            _base = @base;
        }
 
        IPartOne IBase.PartOne
        {
            get { return _base.PartOne; }
            set { _base.PartOne = value; }
        }
 
        public PartOneDeco PartOne
        {
            get { return new PartOneDeco(_base.PartOne); }
            set { _base.PartOne = value.One; }
        }
 
        public int BaseInt
        {
            get { return _base.BaseInt; }
            set { _base.BaseInt = value; }
        }
 
        public string BaseString
        {
            get { return _base.BaseString; }
            set { _base.BaseString = value; }
        }
    }
 
    public class PartOneDeco : IPartOne
    {
        private readonly IPartOne _one;
 
        public PartOneDeco() : this(new PartOne())
        {
        }
 
        public PartOneDeco(IPartOne one)
        {
            _one = one;
        }
 
        public int PartOneInt
        {
            get { return _one.PartOneInt; }
            set { _one.PartOneInt = value; }
        }
 
        public string PartOneString
        {
            get { return _one.PartOneString; }
            set { _one.PartOneString = value; }
        }
 
        public IPartOne One
        {
            get { return _one; }
        }
    }
 
    public class SubDeco : BaseDeco, ISub
    {
        private readonly ISub _sub;
 
        public SubDeco() : this(new Sub())
        {
        }
 
        public SubDeco(ISub sub) : base(sub)
        {
            _sub = sub;
        }
 
        public int SubInt
        {
            get { return _sub.SubInt; }
            set { _sub.SubInt = value; }
        }
 
        public string SubString
        {
            get { return _sub.SubString; }
            set { _sub.SubString = value; }
        }
 
        IPartTwo ISub.PartTwo
        {
            get { return _sub.PartTwo; }
            set { _sub.PartTwo = value; }
        }
 
        public PartTwoDeco PartTwo
        {
            get { return new PartTwoDeco(_sub.PartTwo); }
            set { _sub.PartTwo = value.Two; }
        }
    }
 
    public class PartTwoDeco : IPartTwo
    {
        private readonly IPartTwo _two;
 
        public IPartTwo Two
        {
            get { return _two; }
        }
 
        public PartTwoDeco(IPartTwo two)
        {
            _two = two;
        }
 
        public int PartTwoInt
        {
            get { return _two.PartTwoInt; }
            set { _two.PartTwoInt = value; }
        }
 
        public string PartTwoString
        {
            get { return _two.PartTwoString; }
            set { _two.PartTwoString = value; }
        }
    }
I guess you are probably bored reading them. But there is more, we also have another decorator class for track the changes and raise property change events.

Using T4 to Generate Code

Naturally, code generation, be it compile time or runtime, is what we need. I search around to find a few options:

  1. Commercial product like CodeSmith - Haven’t look any yet.
  2. CodeDom - I used CodeDom in my Web Service Code Generator Project. It is powerful but quite complex to use.
  3. T4 (Text Template Transformation Toolkit – This is the one we are going to give it a try today.
  4. Dynamic proxy using Spring.Net or Castle DP - We have already using Spring.Net dynamic proxy to generate the decorators for property change events and change tracking. With some limitations.
  5. Write our own dynamic proxy using Reflection.Emit API. I used that before, it is also complex but maybe an alternative to option 4 to overcome the limitations. I’ll save this for another post.

After spending a few hours on Oleg Sych’s blog, I started to write a template for produce the code I shown above. The core piece is BvoGeneratorTemplate.tt, which is listed in the end of this post. Let’s take a look at what it can do.

To generate IPartOne and its implementations, all I need to is to add a T4 script file PartOne.tt with below content:

<#@ import namespace="System.Collections.Generic" #>
<#@ template language="C#v3.5" hostspecific="True" debug="True" #>
<#@ output extension="generated.cs" #>
<#@ include file="T4Toolbox.tt" #>
<#@ include file="BvoGeneratorTemplate.tt" #>
 
<#
    var template = new BvoGeneratorTemplate{
     Name = "PartTwo",
     Properties = new List<Property>
        {
            new Property{Type = "int", Name = "PartTwoInt"},
            new Property{Type = "string", Name = "PartTwoString"},
        },
    };
    template.Render();
#>

That automatically generates the code below includes the interface, basic implementation and the decorator class for XML serialization.

// <autogenerated>
//   This file was generated from T4 template BvoGeneratorTemplate.tt.
// </autogenerated>
 
 
#pragma warning disable 1591
namespace ClassLibrary1
{
    public interface IPartTwo 
    {
        int PartTwoInt { get; set;  }
        string PartTwoString { get; set;  }
    }
 
    public partial class PartTwo : IPartTwo
    {
        [CoverageExclude]
        public virtual int PartTwoInt { get; set;  }
        [CoverageExclude]
        public virtual string PartTwoString { get; set;  }
    }
}
namespace ClassLibrary1.Xml
{
    [CoverageExclude]
    public class PartTwoDeco : IPartTwo
    {
        private readonly IPartTwo _partTwo;
        
        public PartTwoDeco(IPartTwo @partTwo)
        {
            _partTwo = @partTwo;
        }
        
        public PartTwoDeco() : this(new PartTwo())
        {
        }
        
        public IPartTwo PartTwo
        {
            get { return _partTwo; }
        }
        public int PartTwoInt 
        {
            get { return _partTwo.PartTwoInt; }
            set { _partTwo.PartTwoInt = value; }
        }
        public string PartTwoString 
        {
            get { return _partTwo.PartTwoString; }
            set { _partTwo.PartTwoString = value; }
        }
    }
}
 
#pragma warning restore 1591

Next let’s take a look at a most complex example Sub.tt:

  1. Sub inherits from Base
  2. Has documentations
  3. A read only computed property
  4. Has a property with a type also generated  by us
<#@ import namespace="System.Collections.Generic" #>
<#@ template language="C#v3.5" hostspecific="True" debug="True" #>
<#@ output extension="generated.cs" #>
<#@ include file="T4Toolbox.tt" #>
<#@ include file="BvoGeneratorTemplate.tt" #>
 
<#
    var template = new BvoGeneratorTemplate {
        Name = "Sub",
        Base = "Base",
        Document = @"
<Summary>
Documentation for ISub
</Summary>
",
         Properties = new List<Property>
        {
            new Property{Type = "int", Name = "SubInt", Document = @"
<Summary>
String property in Sub
</Summary>
"},
            new Property{Type = "string", Name = "SubString"},
            new Property{Type = "IPartTwo", Name = "PartTwo", IsBvo = true},
            new Property{Type = "bool", Name = "IsLarge", IsComputed = true, HasSetter = false},
        },
    };
    template.Render();
#>

Below is the generated code and there are a few things worth mentioning.

  1. There is no implementation for property IsLarge in the Sub class. Developer need to add a regular Sub.cs file to complete the partial class.
  2. In the SubDeco, the IsLarge property is marked as XmlIgnore because a computed property shouldn’t be serialized.
  3. Explicit interface implementation is used for property PartTwo with return type of IPartTwo. And a real PartTwo property is added with return type of PartTowDeco. Because XMLSerializer  doesn’t serialize property of interface type.
// <autogenerated>
//   This file was generated from T4 template BvoGeneratorTemplate.tt.
// </autogenerated>
 
 
#pragma warning disable 1591
namespace ClassLibrary1
{
    /// <Summary>
    /// Documentation for ISub
    /// </Summary>
    public interface ISub : IBase 
    {
        /// <Summary>
        /// String property in Sub
        /// </Summary>
        int SubInt { get; set;  }
        string SubString { get; set;  }
        IPartTwo PartTwo { get; set;  }
        bool IsLarge { get;  }
    }
 
    public partial class Sub : Base, ISub
    {
        [CoverageExclude]
        public virtual int SubInt { get; set;  }
        [CoverageExclude]
        public virtual string SubString { get; set;  }
        [CoverageExclude]
        public virtual IPartTwo PartTwo { get; set;  }
    }
}
namespace ClassLibrary1.Xml
{
    [CoverageExclude]
    public class SubDeco : BaseDeco, ISub
    {
        private readonly ISub _sub;
        
        public SubDeco(ISub @sub) : base(@sub)
        {
            _sub = @sub;
        }
        
        public SubDeco() : this(new Sub())
        {
        }
        
        public ISub Sub
        {
            get { return _sub; }
        }
        public int SubInt 
        {
            get { return _sub.SubInt; }
            set { _sub.SubInt = value; }
        }
        public string SubString 
        {
            get { return _sub.SubString; }
            set { _sub.SubString = value; }
        }
        IPartTwo ISub.PartTwo 
        { 
            get { return _sub.PartTwo; }
            set { _sub.PartTwo = value; }
        }
        public PartTwoDeco PartTwo 
        { 
            get { return new PartTwoDeco( _sub.PartTwo); }
            set { _sub.PartTwo = value.PartTwo; }
        }
        [System.Xml.Serialization.XmlIgnore]
        public bool IsLarge 
        {
            get { return _sub.IsLarge; }
        }
    }
}
 
#pragma warning restore 1591

Other Thoughts

I think the biggest issue here is the documentation. Writing it in the tt file as a string is error prone and unproductive. Possible solutions are:

  1. Define everything in an XML file. Better but still hard to write documentations.
  2. Leaving interfaces in regular cs file, let the tt template parse the interface source file and extract the information. Nice but hard to implement.

Both approach requires further investigation. Your thoughts?

The Template

Finally, here is the template that does all the dirty work.

// <autogenerated>
//   This file was generated from T4 template BvoGeneratorTemplate.tt.
// </autogenerated>
<#@ template language="C#v3.5" hostspecific="True" debug="True" #>
<#@ import namespace="System.Collections.Generic" #>
<#+
public class BvoGeneratorTemplate : Template
{
    public IEnumerable<Property> Properties;
    public string Name;
    public string Base;
    public string Document = string.Empty;
 
    public override string TransformText()
    {
#>
#pragma warning disable 1591
namespace ClassLibrary1
{
<#+
        foreach(string line in Document.Split(new []{'\r','\n'}, StringSplitOptions.RemoveEmptyEntries))
        {
#>
    /// <#=line#>
<#+
        }
#>
    public interface I<#=Name#><#=Base==null? "" : " : I" + Base#> 
    {
<#+
        foreach(Property property in Properties)
        {
            foreach(string line in property.Document.Split(new []{'\r','\n'}, StringSplitOptions.RemoveEmptyEntries))
            {
#>
        /// <#=line#>
<#+
            }
#>
        <#=property.Type#> <#=property.Name#> { <#=property.HasGetter ? "get; " : ""#><#=property.HasSetter? "set; " : ""#> }
<#+
        }
#>
    }
 
    public partial class <#=Name#> : <#=Base==null? "" : Base + ", "#>I<#=Name#>
    {
<#+
        foreach(Property property in Properties)
        {
            if(property.IsComputed) continue;
#>
        [CoverageExclude]
        public virtual <#=property.Type#> <#=property.Name#> { <#=property.HasGetter ? "get; " : ""#><#=property.HasSetter? "set; " : ""#> }
<#+
        }
#>
    }
}
<#+
        var pName = Name;
        if(pName.Length>1 && char.IsUpper(pName[0]) && ! char.IsUpper(pName[1]))
        {
            pName = char.ToLower(pName[0]) + pName.Substring(1);
        }
#>
namespace ClassLibrary1.Xml
{
    [CoverageExclude]
    public class <#=Name#>Deco : <#=Base==null? "" : Base + "Deco, "#>I<#=Name#>
    {
        private readonly I<#=Name#> _<#=pName#>;
        
        public <#=Name#>Deco(I<#=Name#> @<#=pName#>)<#=Base==null? "" : " : base(@"+pName+")"#>
        {
            _<#=pName#> = @<#=pName#>;
        }
        
        public <#=Name#>Deco() : this(new <#=Name#>())
        {
        }
        
        public I<#=Name#> <#=Name#>
        {
            get { return _<#=pName#>; }
        }
<#+
        foreach(Property property in Properties)
        {
            if (!property.IsBvo)
            {
                if(property.IsComputed) {
#>
        [System.Xml.Serialization.XmlIgnore]
<#+
                }
#>
        public <#=property.Type#> <#=property.Name#> 
        {
<#+
                if (property.HasGetter) {
#>
            get { return _<#=pName#>.<#=property.Name#>; }
<#+
                }
                if (property.HasSetter) {
#>
            set { _<#=pName#>.<#=property.Name#> = value; }
<#+
                }
#>
        }
<#+
            }
            else
            {
                var type = property.Type;
                if (type.Length>1 && type[0] == 'I' && char.IsUpper(type[1]))
                {
                    type = type.Substring(1);
                }
#>
        <#=property.Type#> I<#=Name#>.<#=property.Name#> 
        { 
            get { return _<#=pName#>.<#=property.Name#>; }
            set { _<#=pName#>.<#=property.Name#> = value; }
        }
        public <#=type#>Deco <#=property.Name#> 
        { 
            get { return new <#=type#>Deco( _<#=pName#>.<#=property.Name#>); }
            set { _<#=pName#>.<#=property.Name#> = value.<#=type#>; }
        }
<#+
            }
        }
#>
    }
}
 
#pragma warning restore 1591
<#+
        return this.GenerationEnvironment.ToString();
    }
}
    public class Property
    {
        public string Name;
        public string Type;
        public bool IsBvo;
        public bool IsComputed;
        public bool HasGetter = true;
        public bool HasSetter = true;
        public string Document = string.Empty;
    }
#>

Friday, October 23, 2009

Extract The Target Object From The Proxy Generated By Spring.Net

In today’s design session, we called for a quick and dirty hack before we can put a strategic solution in place. The hack is to extract the original target from a proxy of said target.

Given an instance of ITestObject, it is expected to be either of type TestObject or a proxy around an instance of TestObject. Either way, we want to get hold of the TestObject. After digging around the Spring.Net’s source code, we found it is possible. Below is the code to achieve this.

/// <summary> 
/// Extract and return the proxy target if <paramref name="o"/> is a 
/// proxy generated by <see cref="ProxyFactory"/>. Otherwise, return 
/// <paramref name="o"/> itself. 
/// </summary> 
/// <typeparam name="T">The expected type of the target object.</typeparam> 
/// <param name="o"> 
/// An instance of <typeparamref name="T"/> or a proxy of it. 
/// </param> 
/// <returns> 
/// The target instance of <paramref name="o"/> if it is a proxy. 
/// Otherwise, <paramref name="o"/> itself. 
/// </returns> 
/// <exception cref="InvalidCastException"> 
/// If <paramref name="o"/> is neither an instance of <typeparamref name="T"/>, 
/// nor a proxy of <typeparamref name="T"/> instance. 
/// </exception> 
private static T ExtractTarget<T>(object o) 
{ 
    AdvisedProxy ap = o as AdvisedProxy; 
    return (T)(ap == null ? o : ap.m_targetSourceWrapper.GetTarget()); 
} 

Bear in mind that this make your code depends on the detail implementation of the Spring.Net ProxyFactory class, which may be changed in future Spring.Net releases. Hence use it with caution.

Here is the test case for ExtractTarget method.

private static T CreateProxy<T>(T target) 
{ 
    ProxyFactory pf = new ProxyFactory(target); 
    pf.AddInterface(typeof(T)); 
    return (T) pf.GetProxy(); 
} 
 
[Test] public void ProxyTargetTest() 
{ 
    ITestObject target = new TestObject(); 
    Assert.AreSame(target, ExtractTarget<TestObject>(target)); 
 
    ITestObject proxy = CreateProxy<ITestObject>(target); 
    Assert.AreSame(target, ExtractTarget<TestObject>(proxy)); 
} 

Monday, October 12, 2009

MLDonkey Internet Explorer Integration

I have recently setup a home NAS, D-Link DNS-323, and setup MLDonkey to run P2P. It worked great except two problems.

a) it uses a lot of RAM so my poor NAS is running at 1.5M free. DNS-323 only has 64M total. The NAS is still serving other functionality fine so I’m leaving the RAM issue aside for now.

b) I cannot find a decent browser integration solution for Internet Explorer.  But I need to get IE integration working because my other family members, who actually use the P2P most, are still mainly IE users. So here we start.

I started by searching the Google for an existing solution. There is a wiki page about Browser Integration for MLDonkey has comprehensive information but the integration solution for IE is described in only one line.

Mlsubmit.reg

This is the first one I tried as it is the only IE solution listed on the wiki. It manually adds an protocol handler by editing registry. The handler actually reforms the URL then uses IE again open the reformed URL with original ed2k URL as the request parameter. It doesn’t work for two reasons:

  1. Username, password handing. Author use http://username:passwod@site:port/ URL to encode authentication information. Somehow it doesn’t work, It may worked before but IE7 and 8 that I have tried. It gave me unknown site error.
  2. Because it passes ed2k URL as is in the parameter, many special characters are not handled properly. So even after I removed the authentication information (I manually entered when IE prompted me later) the MLDonkey core gets a garbled link and errors out.

Sancho

I installed Sancho, this is a must have for MLDonkey IMHO. It gives a full GUI for MLDonkey Core running on any machine, local or remote. It’s quite small and fast; It’s very useful to submit bittorrent files and check status. The piece of information missing from the wiki page is that Sancho also support protocol association (Search “Input links” in FAQ). In Vista, you’ll need to run it as administrator for it to successfully update the registry, otherwise you get no error but nothing happens too.

So now what’s the problem with Sancho? Actually, it is not the Sancho’s problem, but rather, as always, the broken Internet Explorer when it handles international characters. If an URL contains non-ascii characters and encoded, instead passing it as is to the protocol handler, IE decodes it. It would be fine if it decoded correctly, but unfortunately no, it’s URL decoding logic is completely broken all the way up to IE8.

DonkeyInput

Now I reached the dead end on this. OK, if I cannot find one, I’ll write one. Hence born the DonkeyInput. It’s a tiny (21K) windows application written in C#.

image

DonkeyInput can be downloaded here, it needs no installation. The first run of the program will automatically register itself as ed2k protocol handler, you must run it as administrator on Vista for the first time to allow it successfully change the registry.

Now, restart your browser and click on an ed2k link. The windows above should pop up. All you need to do is set the correct options and click OK button.

Note:

  1. be a little patient if you are adding multiple URLs
  2. be a little patient after you click on OK button for it the send the request to MLDonkey Core.

Thursday, September 10, 2009

How NUnit Handles Test Fixture as Inner Class

The Problem

Will NUnit execute the test fixture defined as inner class when I test run the enclosing test fixture? The answer is, it depends (as of version 2.5.2). In most of cases it won't, but if the enclosing test fixture is a generic type, it will.

Here is the test case to reproduce this:

namespace Demo
{
    [TestFixture] public class A { //plain normal
        [Test] public void Bar() { }
        [TestFixture] public class Inner {
            [Test] public void Foo() {}
        }
    }
 
    [TestFixture(typeof(int))] public class B<T> { // generic
        [Test] public void Bar() { }
        [TestFixture(typeof(int))] public class Inner {
            [Test] public void Foo() {}
        }
    }
 
    [TestFixture("dummy")] public class C { // parameterized non-generic
        public C(string dummy){}
        [Test] public void Bar() { }
        [TestFixture(typeof(int))] public class Inner {
            [Test] public void Foo() { }
        }
    }
}

And the result:

C:\Demo>nunit-console.exe Demo.Tests.dll /run="Demo.A" /labels
Selected test: Demo.A
***** Demo.A.Bar
 
Tests run: 1, Errors: 0, Failures: 0, Inconclusive: 0, Time: 0.0262504 seconds
  Not run: 0, Invalid: 0, Ignored: 0, Skipped: 0
 
C:\Demo>nunit-console.exe Demo.Tests.dll /run="Demo.B<T>" /labels
Selected test: Demo.B<T>
***** Demo.B`1+Inner[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Foo
***** Demo.B`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Bar
 
Tests run: 2, Errors: 0, Failures: 0, Inconclusive: 0, Time: 0.0337505 seconds
  Not run: 0, Invalid: 0, Ignored: 0, Skipped: 0
 
C:\Demo>nunit-console.exe Demo.Tests.dll /run="Demo.C" /labels
Selected test: Demo.C
***** Demo.C.Bar
 
Tests run: 1, Errors: 0, Failures: 0, Inconclusive: 0, Time: 0.0350005 seconds
  Not run: 0, Invalid: 0, Ignored: 0, Skipped: 0

My Thoughts

Now which behavior do I prefer? I would like to include the inner test fixture classes when running the enclosing one. Why? that's the only reason so far I need to create inner test fixture class. And here is the use case:

  1. I have MyCollection<T> : ICollection<T>, ICollection that is the subject under test.
  2. I have common reusable test fixture CollectionTestFixture<T> and CollectionTestFixture contain functional test cases for types that implement ICollection<T> and/or ICollection.
Test implementation A, Create three(3) separate test fixtures
  • MyCollectionGenericTests<T> : CollectionTestFixture<T>
  • MyCollectionNonGenericTests : CollectionTestFixuture
  • MyCollectionTests<T> // specific test cases

Pros:

  • Simple
  • Works

Cons:

  • Must run 3 test fixture to test one class
  • Difficult (impossible if using TD.Net) to run overall code coverage for MyCollection<T> class
  • Test result are not grouped together when there is MyCollectionSomeElseTest.
Test implementation B, use dedicated namespace
  • MyCollection.GenericTests<T> : CollectionTestFixture<T>
  • MyCollection.NonGenericTests : CollectionTestFixuture
  • MyCollection.Tests<T> // specific test cases

Pros:

  • Works
  • Can easily run all tests for MyCollection and get overall coverage

Cons:

  • Creating one folder (matching namespace) for one class to be tested result in very busy project layout and hard to navigate when there are a lot of such scenarios.
  • There will be a lot of repeated type names, e.g. GenericTests<T>. Otherwise MyCollection.MyCollectionGenericTests<T> makes the label reads much longer which is a bad thing.
Test implementation C, use inner classes
  • MyCollectionTests<T> // specific test cases
  • MyCollectionTests.AsGeneric<T> : CollectionTestFixture<T>
  • MyCollectionTests.AsNonGeneric : CollectionTestFixuture

Pros:

  • Can easily run all tests for MyCollection and get overall coverage
  • No additional directories to create and navigate.
  • Common methods can be easily reused by inner classes.
  • Labels read naturally

Cons:

  • Doesn’t work for non-generic enclosing test fixture, but hoping it will work…
The Winner

It is not difficult to conclude that the best implementation is C if NUnit can support it consistently. And IMHO, inner classes are members of enclosing class from the language (logical) perspective although CLR implemented (physical) the other way. I wish test framework implements the logical meaning because that’s what most developers familiar with.

Test Fixture Aggregation

I recall there was a talk about the ability to quickly create a new test fixture by aggregating test cases from multiple reusable test fixtures. The inner class approach is my proposal to the problem. Together with the ability to specify including/excluding of test cases in the inherited fixture may provide a complete solution.

My Wishes

  1. Change NUnit to always consider test cases of inner class as an integral part of the enclosing test fixture. And execute then when the enclosing test fixture is specified to execute.
  2. NUnit-GUI should organize the inner class under the enclosing class in its tree structure.
  3. This one is minor and not important to me but it would be nice if NUnit can hide the implementation detail of CLR and translate to the dot notation for inner class like what the language does.

Tuesday, August 11, 2009

NUnit 2.5.2 Released

The project is very active and Charlie is quite responsive to bug fixes and feature requests. I have recently reported two bugs in one discussion and two feature requests (1, 2). Charlie was able to quickly apply the patch for one bug and implemented the instance of exception assert feature right before 2.5.2 release.

I have heard some good stories of MbUnit as well, it's a mixed feeling to see two open source test framework competing each other. Wouldn't it be nice if they can work together instead of reinventing wheels twice? The combined effort could have produced much more complete test system...

Friday, July 17, 2009

Intercept Explicit Interface Implementation with Inheritance Based Proxy

This is continue from my last post, Intercept Non-Virtual Interface Implementation, Implicit or Explicit.

Krzysztof was absolutely right that it throws MethodAccessException if you just call it. It only works with delegate. But how difficult and/or expensive it is to use delegate?

  1. For each explicit method that we want to intercept, we need to define a new delegate type that matches the method signature
  2. We need to defined a static field of above generated delegate type for each method
  3. Then we use the static delegate instance to make the call to the explicit implementation method in the parent class

This doesn't sound bad to me. There is nearly no runtime CPU overhead, but to hold the generated delegate types, we need some memory. I believe this is well acceptable. After all, we can further optimized it by caching the generated delegate to be reused by the methods with same signature.

I took this as a good opportunity for me to learn the Reflection.Emit API. Thanks to Krzysztof's for the article Working effectively with Reflection.Emit, which led me to the proper tools and approach to start with. Here is what I have achieved.

        public interface IFoo
        {
            void FooMethod(out int i);
            int BarMethod(int i);
        }

        public class Foo : IFoo
        {
            void IFoo.FooMethod(out int i)
            {
                Console.WriteLine("From Foo.FooMethod!");
                i = 100;
            }

            int IFoo.BarMethod(int i)
            {
                return i*i;
            }
        }

        public static void Main(string[] args)
        {
            const string moduleName = "DynamicModule";
            ModuleBuilder mb = EmitUtils.CreateDynamicModule(moduleName);

            Type t = OverrideFoo(mb);

            var proxy = (IFoo) t.GetConstructor(Type.EmptyTypes).Invoke(null);

            int result;
            proxy.FooMethod(out result);
            Console.WriteLine(result);
            Console.WriteLine(proxy.BarMethod(5));
        }

        private static Type OverrideFoo(ModuleBuilder mb)
        {
            TypeBuilder tb = mb.DefineType(
                mb.Assembly.GetName().Name + ".Bar", 
TypeAttributes.Public | TypeAttributes.Class, typeof(Foo), new Type[]{typeof(IFoo)}); var iFooMethods = typeof (IFoo).GetMethods(); var overriders = new List<ExplicitMethodOverrider>(iFooMethods.Length); foreach (MethodInfo iFooMethod in iFooMethods) { overriders.Add(new ExplicitMethodOverrider(mb, tb, iFooMethod)); } Type t = tb.CreateType(); // Initialize static fields for delegates foreach (ExplicitMethodOverrider overrider in overriders) { overrider.InitializeDelegate(t); } return t; }

The output of above program is:

Proxy before call Void DynamicProxy.Program.IFoo.FooMethod(Int32 ByRef)
From Foo.FooMethod!
Proxy after call Void DynamicProxy.Program.IFoo.FooMethod(Int32 ByRef)
100
Proxy before call Int32 DynamicProxy.Program.IFoo.BarMethod(Int32)
Proxy after call Int32 DynamicProxy.Program.IFoo.BarMethod(Int32)
25

The core of this is consisted of two piece of code. One emits the delegate type based on a the MethodInfo of the explicitly implemented base class method. This is done by a static method EmitUtils.GenerateDelegateType, mostly copy from Joel Pobar. Another one emits a static field of delegate type and implement the interface method to call the delegate, which in turn calls the explicit implementation in the base class. This logic is in the the ExplicitMethodOverrider class on which I spent most of my time. The ExplicitMethodOverrider class also provide an initialization method to populate the static field after the type is created.

All the source code can be found here.