Polymorphic lists in RavenDB / JSON

Recently I'm doing a lot of playing around with RavenDB, a pure .Net Document database.

By default RavenDB can't handle documents containing lists of different types. That's not exactly RavenDB's fault, as the documents are stored as JSON. One way to solve this, is by providing a custom JsonContractResolver, as Ayende already pointed out.

While using JsonContractResolver definitly works, I think, I would prefer to do this using an attribute. Fortunately Newtonsoft.Json already allows this, so I can do:

public interface IBar
{
}

public class Foo
{
    public string Id { get; set; }

    [JsonConverter(typeof(PolymorphicListConverter))]
    public List<IBar> Bars { get; set; }

    [JsonConverter(typeof(PolymorphicListConverter<List<IBar>>))]
    public IList<IBar> NonConcreteBars { get; set; }

    [JsonConverter(typeof(PolymorphicListConverter))]
    public ArrayList NonGenericBars { get; set; }
}

public class BarMaid: IBar
{
    public string Something { get; set;}
}

public class BarTender: IBar
{
    public string SomethingElse { get; set;}
}

Note that PolymorphicListConverter can take a generic type argument, because it might need to know, what type of list to create on deserialization, if the property doesn't use a concrete type.

The PolymorphicListConvert will now take care of the serialization/deserialization:

public class PolymorphicListConverter<TListType> 
  : PolymorphicListConverter where TListType : class, IList
{
    public PolymorphicListConverter()
        : base(typeof (TListType))
    {
    }
}

public class PolymorphicListConverter : JsonConverter
{
    private readonly Type _explicitListType;

    public PolymorphicListConverter()
    {
    }

    protected PolymorphicListConverter(Type type)
    {
        _explicitListType = type;
    }

    public override void WriteJson(JsonWriter writer, object value,
      JsonSerializer serializer)
    {
        writer.WriteStartArray();
        foreach (var item in (IEnumerable) value)
        {
            writer.WriteStartObject();

            writer.WritePropertyName("CrlType");
            writer.WriteValue(item.GetType().AssemblyQualifiedName);

            writer.WritePropertyName("Value");
            serializer.Serialize(writer, item);

            writer.WriteEndObject();
        }
        writer.WriteEndArray();
    }

    public override object ReadJson(JsonReader reader, 
        Type objectType, object existingValue,
        JsonSerializer serializer)
    {
        var list = (IList) Activator.CreateInstance(
          _explicitListType ?? objectType);

        while (reader.Read())
        {
            if (reader.TokenType == JsonToken.EndArray)
                break;

            reader.Read(); //CrlType prop name
            reader.Read(); //actual type
            var type = Type.GetType((string) reader.Value);
            reader.Read(); // value property
            reader.Read(); // actual value
            list.Add(serializer.Deserialize(reader, type));
            reader.Read(); // end object
        }
        return list;
    }

    public override bool CanConvert(Type objectType)
    {
        var deserializationType = (_explicitListType ?? objectType);
        return typeof (IEnumerable).IsAssignableFrom(objectType) &&
               deserializationType.IsClass && 
               !deserializationType.IsAbstract;
    }
}

Published on 08/06/2010 at 17:23 by , tags , , ,

Microsoft is not going to fix the bugs, I found :-(

Last week I found an issue with Microsofts C# compiler, which does not generate warnings about unused variables in some cases. I've reported it to Microsoft and to my surprise, got an answer today.

Unfortunately they are not going to fix it :-(

...our guidance for customers who are interested in discovering unused elements in their code is to use FxCop. ...we are not actively enhancing the compiler's detection of these conditions and will not be making the changes you suggest.

FeedBackID 362970

Published on 28/08/2008 at 12:42 by , tags , , ,

The Microsoft .NET C# compiler has it's issues as well

While working on porting StructureMap to Mono I stumbled across some bugs in the Mono C# compiler. I did expected this, fixed or worked around the bugs and reported them. What I didn't expected, was to find some trivial bugs in Microsoft's C# compiler as well. It's nothing critical, but annoying. Consider this code:

using System;

namespace Test
{
    public class BuggyClass
    {
        private string foo = String.Empty;
        private int _bar = 5;
        private int _wrongBar = 5;

        public int Bar
        {
            get { return _bar; }
            set { _wrongBar = value; }
        }

        public void DoSomething()
        {
            string msg = "foo" + 1.ToString();
        }
    }
}

It contains three variables and fields which are never used, so I would expect the compiler to emit three warnings. But csc does nothing - in none of three different versions:

c:\tmp\--->C:\WINDOWS\Microsoft.NET\Framework\v3.5\csc.exe /warn:4 /target:library test.cs 
Microsoft (R) Visual C# 2008 Compiler Version 3.5.30729.1
, fr Microsoft (R) .NET Framework Version 3.5
Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten.


c:\tmp\--->C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe /warn:4 /target:library test.cs 
Microsoft (R) Visual C# 2005, Compilerversion 8.00.50727.3053
fr Microsoft (R) Windows (R) 2005 Framework, Version 2.0.50727
Copyright (C) Microsoft Corporation 2001-2005. Alle Rechte vorbehalten.


c:\tmp\--->C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\csc.exe /warn:4 /target:library test.cs 
Microsoft (R) Visual C# .NET-Compilerversion 7.10.6001.4
fr Microsoft (R) .NET Framework, Version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. Alle Rechte vorbehalten.

This point goes to the Mono C# compiler, for correctly identifying these warnings:

c:\tmp\--->C:\Programme\Mono-1.9.1\lib\mono\1.0\mcs.exe /warn:4 /target:library test.cs 
test.cs(19,20): warning CS0219: The variable `msg' is assigned but its value is never used
test.cs(7,24): warning CS0169: The private field `Test.BuggyClass.foo' is assigned but its value is never used
test.cs(9,21): warning CS0169: The private field `Test.BuggyClass._wrongBar' is assigned but its value is never used
Compilation succeeded - 3 warning(s)

You might say, that this is just a trivial warning and usually it doesn't hurt to have some unused variables around. But look at the Bar property above. It sets a different value than the one it returns. Looks like a serious bug to me - maybe caused by wrongly renaming the field. If this isn't covered by a unit test and the compiler doesn't even give a warning, chances are good, that this bug will find it's way into production code.

I've also reported this to Microsoft's Bug Nirvana BugTracker (FeedbackID 362970).

Published on 22/08/2008 at 13:28 by , tags , , ,

Different ways of riding a Rhino

It's now about a year ago, that I've started to use Rhino Mocks for my mocking needs in .NET development. In the beginning I didn't liked it very much. This was mainly because of its Expect-syntax:

Expect.On(subject).Calls(subject.SaveTheWorld()).Returns(False);

When getting in touch with Rhino Mocks the first time, I wasn't won over by this "wanna be a real English sentence" approch, nowadays called "fluent interface". But on the other side Rhino Mocks had some nice features, I really liked. Espeacially it's easy way of dealing with generics has been decisive to give it a chance. It certainly wasn't a love at the first sight, but today I wouldn't miss it anymore.

There are basically three different ways of using Rhino Mocks, coming with their own advantages and disadvantages. Everybody knows the standard way of working with Rhino Mocks, but I have the feeling, that the other two Rhino Mocks syntaxes are a little bit unappreciated or not very well known. I hope to give you an understanding of the alternative Rhino Mocks syntaxes, but let's start with the standard, which looks like this:

MockRepository mocks = new MockRepository();
IDependency dependency = mocks.CreateMock<IDependency>();
Expect.Call(dependency.GetSomething("parameter")).Return("result");
dependency.DoSomething();
mocks.ReplayAll();
Subject subject = new Subject(dependency);
subject.DoWork();
mocks.VerifyAll();

The above code basically sets up a mock for the IDependency interface, that gets passed into the Subject class. Two expectations are then defined for the mock. The first expects the GetSomething() method to be called with a parameter and returning a value. The second expects the void method DoSomething() to be called. After calling subject.DoWork(), it is verified with mocks.VerifyAll(), if all the expectations on the mock have been met.

It's only eight lines of code, but I don't consider this very readable. Some comments and empty lines can help here:

MockRepository mocks = new MockRepository();
IDependency dependency = mocks.CreateMock<IDependency>();

// define expectations
Expect.Call(dependency.GetSomething("parameter")).Return("result");
dependency.DoSomething();
mocks.ReplayAll();

// run test subject
Subject subject = new Subject(dependency);
subject.DoWork();

// verify expectations
mocks.VerifyAll();

This looks better, but as we all know, comments are a code smell, so let's take a look at another way of expressing our intend, by using Rhino Mocks' "Record-Playback" syntax:

MockRepository mocks = new MockRepository();
IDependency dependency = mocks.CreateMock<IDependency>();

using (mocks.Record())
{
    Expect.Call(dependency.GetSomething("parameter")).Return("result");
    dependency.DoSomething();
}

using (mocks.Playback())
{
    Subject subject = new Subject(dependency);
    subject.DoWork();
}

What we've done with the comments before, is now replaced by "using (mocks.Record())" and "using (mocks.Playback())". It might be a matter of taste, but I find this much more readable. Another advantage of this syntax is, that ReplayAll() and VerifyAll() are implicitly called. I can't count the number of times, I missed one of these calls and then wondering, why the test doesn't work.

Recently introduced in Rhino Mocks 3.2 comes another syntax, which tries to follow the "fluent interface" methodology:

MockRepository mocks = new MockRepository();
IDependency dependency = mocks.CreateMock<IDependency>();

With.Mocks(mocks).Expecting(delegate
{
    Expect.Call(dependency.GetSomething("parameter")).Return("result");
    dependency.DoSomething();
})
.Verify(delegate
{
    Subject subject = new Subject(dependency);
    subject.DoWork();
});

Again ReplayAll() and VerifyAll() are implicitly called, eliminating a big possible cause of failure. One advantage over the Record-Playback syntax is it's fluent interface. Intellisense will guide you step by step, each time you type the ".". A small drop of bitterness is the usage of anonymous delegates. The delegate keyword always looks kinda "noisy" to me, but that's something I can live with.

To draw a conclusion, I think the Record-Playback as well as the fluent syntax are much more readable and decreases the human error factor by implicitly calling ReplayAll() and VerifyAll(). This makes me prefer these syntaxes over the standard way most of the time. Usually I now use the fluent "With.Mocks(...).Expecting(...).Verify(...)"-way for easy to set up expectations. When more complex expectations have to be configured or the code to be verified is more complex, I find the Record-Playback syntax more handy.

I rarely use the standard syntax nowadays. When I'm using it, then mostly for setting up simple stubs like this:

MockRepository mocks = new MockRepository();
IDependency dependency = mocks.DynamicMock<IDependency>();

SetupResult.For(dependency.GetSomething("")).Return("result");
mocks.ReplayAll();

Subject subject = new Subject(dependency);
subject.DoWork();

For a complete description of the different Rhino Mocks syntaxes, take a look at its documentation.

Published on 21/08/2007 at 12:53 by , tags , , , , , ,

Powered by Publify | Photo Startup stock photos