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 , , ,

C# - Getting rid of casting-parenthesis

Normally casting should be avoided if possible and when casting is necessary, use the as-operater and check the result for null! But sometimes a plain cast seems to be valid and necessary and when this is the case, I absolutely hate to type the parenthesis. So my new little friend is this extension method:

public static class CastExtension
{
    public static T Cast<T>(this object obj)
    {
        return (T) obj;
    }
}

instead of:

((IBar) foo).DoSomething();

you can now trade two parenthesis for two angle brackets:

foo.Cast<IBar>().DoSomething().

Doesn't seem to be much of a difference, but it types much nicer!

Published on 01/02/2010 at 12:01 by , tags ,

WPF-Howto #1 - Making your buttons beep

During the last weeks I've been doing a lot of WPF when migrating a MVC (Model-View-Controller) based WinForms application to the Windows Presentation Foundation using the MVVM (Model-View-ViewModel) pattern and the fabulous Caliburn Framework.

When I touched WPF the first time about 1,5 years ago, my first thought was: "Oh no... not just XML again!". But over the time, I started to love it. I'm feeling very comfortable with editing the xaml files by hand, without the support of any design tool - the basic and commonly used layouts and components are as easy to use as HTML. When I did some GTK development with Glade yesterday, I painfully missed my beloved Stackpanel, Grid and Margin Property :-)

While 90% of the daily work with WPF is pretty easy, the other 10% sometimes can be tricky. Thankfully in most cases I'm not the first one that encounters a specific problem and often find a solution in a blog or forum post.

"Time to post some hopefully helpful tips myself", I thought, and here we go:

Click me!

For a WPF touch screen interface, I required all buttons in the application to make a "click" sound when beeing pressed.

"There must be a way to do this in XAML only", I thought and came up with this solution:

<Window x:Class="RoutedClickEvent.Window1" ...>
<Window.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
        <EventTrigger.Actions>
            <SoundPlayerAction Source="/RoutedClickEvent;component/click.wav" />
         </EventTrigger.Actions>
    </EventTrigger>
</Window.Triggers>
...

This works fine - Easy Peasy!

But not so fast my young padawan!

If I have anything in a buttons event handler, that causes a noticable delay (e.g. showing a modal dialog), the button sound will be delayed as well.

The reason is, that the Click event is a bubbling event. It bubbles from the button itself up to the Window. That means, the buttons click event handler will be executed, before the event is triggerd on the window, causing the click sound to appear delayed.

My next thought was, to go with the PreviewMouseDown event (which is a tunneling event, that will be handeled before the buttons click event). Unfortunately, this required some code:

private void Window_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    var source = e.OriginalSource as DependencyObject;
    var button = source as ButtonBase;
    while (button == null && source != null)
    {
         source = VisualTreeHelper.GetParent(source);
         button = source as ButtonBase;
     }
     if (button != null)
     {
         var stream = Application.GetResourceStream(new Uri("pack://application:,,,/PreviewMouseDownHandler;Component/click.wav"));
         new SoundPlayer(stream.Stream).Play();
     }
 }

Works fine, but walking up the visual tree to figure out, if the mouse down event happend on a button, feels terribly wrong!

"Use the Styles Luke!" - Now I tried to apply a style to the buttons, that makes them play the click sound when pressed. You indeed can wire events with the <EventSetter> tag. But I want my style to be defined in a separate ResourceDictionary, so I don't have any instance I could wire the event to.

And now it becomes a little bit weired - I created a code behind file for the ResourceDictionary! I didn't really expected this to work, but it did! To do so, just add a x:Class attribute to the ResourceDictionary, create a new class file with "MyResourceDictionary.xaml.cs" and the partial class "MyResourceDictionary" and vour la! If you want the code behind file to appear as a child of the xaml file in VisuaStudio, you can also add a DependentUpon tag to the code behind node in the *.csproj:

<Compile Include="NoisyButton.xaml.cs">
    <DependentUpon>NoisyButton.xaml</DependentUpon>
</Compile>

Now that the ResourceDictonary has a code behind, I can wire the click event in the style settings to the code behind class:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="StyleWithCodeBehind.NoisyButton">
    <Style TargetType="Button">
        <EventSetter Event="PreviewMouseDown"
                     Handler="OnClick" />
    </Style>
</ResourceDictionary>

public partial class NoisyButton
{
    private void OnClick(object sender, RoutedEventArgs e)
    {
        var stream = Application.GetResourceStream(new Uri("pack://application:,,,/StyleWithCodeBehind;Component/click.wav"));
        new SoundPlayer(stream.Stream).Play();
    }
}

Now just merge the ResourceDictionary in the main window or App and you will hear the buttons click:

<Window x:Class="StyleWithCodeBehind.Window1" ...>
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="NoisyButton.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <StackPanel>
        <Button>Click me!</Button>
        <Button Click="Button_Click">Click me harder!</Button>
    </StackPanel>
</Window>

A ResourceDictionary with a code behind file is kinda cool, but there's an easier way to make the buttons click. Indeed it's so easy, I should have come up with this in the first place:

<Style TargetType="Button">
    <Style.Triggers>
        <EventTrigger RoutedEvent="PreviewMouseDown">
            <SoundPlayerAction Source="/XamlOnlyClickingButton;component/click.wav" />
        </EventTrigger>
    </Style.Triggers>
</Style>

Lesson learned - don't think too complicated!

Download Source Code

Published on 20/07/2009 at 19:30 by , tags , , , , ,

RSpec'ing a Rake TaskLib

I thought it would be a good idea to use RSpec for creating custom Rake TaskLib's, but I couldn't find any examples for this. So here's a pretty simple one from a project I'm working on at the moment. A TaskLib for creating a Mono resource generator task.

This TaskLib should create a file task for a .resources file, depending on a .resx file:

require 'rake'

describe ResgenTask do
    it 'should create a file task with the *.resource file as target and *.resx as dependency' do
        ResgenTask.new 'foo.resources'
        Rake::Task.tasks.should satisfy do |tasks|
            for task in tasks
                if task.name == 'foo.resources' and task.prerequisites.include?('foo.resx')
                    break true
                end
            end
            false
        end
    end
end

This doesn't work because of the missing ResgenTask, so we create it:

require 'rake/tasklib'

class ResgenTask < Rake::TaskLib
    def initialize(target)
    end
end

The specification now fails:

>spec resgentask_spec.rb --format specdoc

ResgenTask
- should create a file task with the *.resource file as target and *.resx as dependency (FAILED - 1)

1)
'ResgenTask should create a file task with the *.resource file as target and *.resx as dependency' FAILED
expected  to satisfy block
./resgentask_spec.rb:11:

Finished in 0.005009 seconds

1 example, 1 failure

But before we implement this specification, let's refactor it a little bit. This is much more readable:

it 'should create a file task with the *.resource file as target and *.resx as dependency' do
    ResgenTask.new 'foo.resources'
    Rake::Task.tasks.should have_file_task('foo.resources').depending_on('foo.resx')
end

Because there is no have_file_task, we need to create a custom matcher:

module RakeMatchers

class FileTaskMatcher
    def initialize(filename)
         @target = filename
         @source = nil
    end

    def depending_on(source)
        @source = source
        return self
    end

    def matches?(tasks)
        @tasks = tasks
        for task in tasks
            if (task.name == @target) and (not @sources or task.prerequisites.include?(@source))
                return true
            end
        end
        return false
    end

    def failure_message
         "expected file target #{@target} with dependency #{@source} to be in task list [#{@tasks.join(' ')}]"
    end

    def negative_failure_message
         "expected file target #{@target} with dependency #{@source} not to be in task list [#{@tasks.join(' ')}]"
    end
end

def have_file_task(filename)
    return FileTaskMatcher.new(filename)
end

end

In order to be able to use this matcher, we simply include it:

describe ResgenTask do
    include RakeMatchers

    it 'should create a file task with the *.resource file as target and *.resx as dependency' do
        ResgenTask.new 'foo.resources'
        Rake::Task.tasks.should have_file_task('foo.resources').depending_on('foo.resx')
    end
end

It still fails, but with a much nicer output:

>spec resgentask_spec.rb --format specdoc

ResgenTask
- should create a file task with the *.resource file as target and *.resx as dependency (FAILED - 1)

1)
'ResgenTask should create a file task with the *.resource file as target and *.resx as dependency' FAILED
expected file target foo.resources with dependency foo.resx to be in task list []
./resgentask_spec.rb:52:

Finished in 0.005116 seconds

1 example, 1 failure

Time to implement this specification:

class ResgenTask < Rake::TaskLib
    def initialize(target)
        file target => target.gsub('.resources', '.resx')
    end
end

The next specification will describe the behavior of the file task:

it 'should create a file task that runs resgen2' do
        ResgenTask.new 'foo.resources'
end

But wait a moment! Before letting ResgenTask.new create a new file task, the old tasks should be dropped:

describe ResgenTask do
    include RakeMatchers

    before :each do
        Rake::Task.clear
        @tasklib = ResgenTask.new 'foo.resources'
    end

Ok - now we can think about, how to test the generated task. What it should do, is run sh('resgen2 foo.resources foo.resx'). We don't want to actually run sh(), so we need to mock it. sh() is defined in the module FileUtils. My first guess was, to use FileUtils.should_receive(:sh), but this didn't work. To be honest, I have no idea, what's the right place to mock sh(). But the simplest solution is to create a mocked sh() member method on the task lib:

it 'should create a file task that runs resgen2' do
    @tasklib.should_receive(:sh).with('resgen2 foo.resources foo.resx')
    Rake::Task['foo.resources'].execute(nil)
end 

The specification fails, so let's implement it:

class ResgenTask < Rake::TaskLib
    def initialize(target)
       file target => target.gsub('.resources', '.resx') do |task|
           sh("resgen2 #{task.name} #{task.prerequisites}")
       end
    end
end

To add an extra goody, the compiled resource file should be removed on the clean target automatically:

it 'should add the *.resources file to the clean target' do
    CLEAN.should include('foo.resources')
end

This can be implemented as:

def initialize(target)
    CLEAN.include(target) 
    file target => target.gsub('.resources', '.resx') do |task|

The final set of specs now looks like this:

describe ResgenTask do
    include RakeMatchers

    before :each do
        Rake::Task.clear
        CLEAN.celar
        @tasklib = ResgenTask.new 'foo.resources'
    end

    it 'should create a file task with the *.resource file as target and *.resx as dependency' do
        Rake::Task.tasks.should have_file_task('foo.resources').depending_on('foo.resx')
    end

    it 'should create a file task that runs resgen2' do
        @tasklib.should_receive(:sh).with('resgen2 foo.resources foo.resx')
        Rake::Task['foo.resources'].execute(nil)
    end 

    it 'should add the *.resources file to the clean target' do
        CLEAN.should include('foo.resources')
    end
end

...and is implemented by:

class ResgenTask < Rake::TaskLib
    def initialize(target)
        CLEAN.include(target) 
        file target => target.gsub('.resources', '.resx') do |task|
            sh("resgen2 #{task.name} #{task.prerequisites}")
        end
    end
end

It's a pretty simple example, but it should be enough to get started.

Published on 04/10/2008 at 12:01 by , tags , , ,

Evaluating build tools for altdotmono.org - part two

Three days ago I thought about which build tool to use for the altdotmono.org projects. I came up with the conclusion, that CMake, SCons and Autotools should be on my short list.

First a small correction: I wrote, that Rant doesn't have any native CSharp support. That's not true! It has a CSharp generator, that can be used as simple as this:

import 'csharp'
gen CSharp, "example.dll", :sources => sys["**/*.cs"]

Unfortunately it doesn't work very well. Simply adding a reference makes it fail:

gen CSharp, "example.dll", :sources => sys["**/*.cs"],
                           :libs    => ["System.Web"]

rant: [ERROR] in file `/usr/lib/ruby/1.8/rant/rantlib.rb', line 577: 
              in prerequisites: no such file or task: `System.Web'

This should be easy to fix in Rant, I just added a bug report. Sadly Rant doesn't seem to be very popular. There has been no commit within a year, only ten bug reports within 3 years and although Rant is packaged in Debian, not a single package in Lenny uses Rant as a build tool. (But I should also add, that not more than six packages build-depend on Rake compared to more than 100 packages depending on CMake and more then 50 packages depending on SCons.)

Rake is much more popular but misses some features, that Rant provides (e.g. MD5 checksums instead of timestamps for dependency checking). I haven't really considered Rake yet, because I couldn't find any project using it for building C#/Mono projects. But after playing around with SCons and CMake I didn't had the feeling of having found the right tool, so I tried Rake anyway.

I wrote a custom TaskLib supporting gmcs within half an hour, so that my Rakefile for building two libs now looks like this:

require 'rake'
require 'rake/gmcs'

task :default => ['StructureMap.dll', 'StructureMap.AutoMocking.dll']

signingKey = 'structuremap.snk'


#
# The Core StructureMap Assembly
#
sources    = FileList['StructureMap/**/*.cs']
references = ['System.Web', 'System.Configuration']

Rake::GmcsTask.new 'StructureMap.dll' => {:sources => sources,
  :references => references, :keyfile => signingKey}


#
# StructureMap Rhino.Mocks automocking support
#
sources    = FileList['StructureMap.AutoMocking/**/*.cs']
references = ['#../../Rhino.Mocks.dll', '#StructureMap.dll']

Rake::GmcsTask.new 'StructureMap.AutoMocking.dll' => {:sources => sources,
  :references => references, :keyfile => signingKey}

This comes pretty close to what I would like to have. The Gmcs task basically reads:

"Build StructureMap from the list of sources, linking to the list of references and sign it with the signingKey."

GmcsTask will create a Rake file task and will automatically make it pre-depend on the sources, the local references and the key file. This means, that StructureMape.Automocking.dll will only be built. if the timestamp of the sources, of StructureMap.dll, RhinoMocks.dll or the key file change. Because I can't make a dependency to a reference called "System.Web", I needed a way to specify which references are local file dependencies and which are not. This is simply done by prefixing the reference with '#', something I saw in the SCons build files of Diva.

I think this is pretty easy and it can probably be made even easier by writing a Visual Studio *.csproj-Parser, which extracts the sources, references and resources from the project files. And by even adding a solution parser, the whole build of multiple projects might be stripped down to something like:

task :default => SolutionParser.new('StructureMap.sln').ProjectTasks

"Easy Peasy" as Jamie Oliver would say. I'm not sure if it is a good idea to completely rely on the Visual Studio solution and project files, but I think I will try to drive the Rake approach for building the Alltdotmono projects a little bit further.

Published on 27/09/2008 at 12:35 by , tags , , , ,

Searching for the holy grail of build systems

For my new OpenSource project "altdotnet.org", which is about making OSS from the Microsoft .NET world available to Linux/Mono, I have to decide now, which build system to use. There's a bunch of build tools to be considered: NAnt, Autotools, CMake, SCons, Waf, Rant, Rake, Waf.

While NAnt is more or less the only tool, which may already be used by the original author in the Microsoft .NET world, it's not simply portable to Linux/Mono. Often NAnt is just used to simply run msbuild on the project files or solutions. But the msbuild counterpart on Mono isn't very actively maintained and doesn't support VisualStudio 2008 yet. Besides this NAnt is too much XML for my taste.

Autotools seems to be the preferred approach on Linux. A quick scan for *.dll's in the Debian project showed, that most of these packages use Autotools for building Mono libs and applications. When I asked someone from the Debian Mono packaging project, how to package something using Nant, he also advised me, to go with a plain Makefile and Autotools instead. Monodevelop can create the required Autotools files and takes cares of all the dirty details, so this is not so hard to get going. But I'm not a big Autotools fan. I love it as a user, when ./configure and make just work out of the box, but as a Maintainer I hate Autotools, because I never fully understood, how everything really works inside.

CMake and the Python based SCons offer an alternative to the Autotools. Both don't really come with any native support for C#/Mono, but can easily be used for this. CMake is used within the KDE bindings to build Mono libs and a quick search for Scons brought up at least two projects (Diva and DCSharp) using it for building Mono applications. So there is plenty of sample code available to getting started with. While CMake uses it's own macro language and SCons is plain Python, the learning curve for CMake is probably a little bit steeper. But while looking at the above mentioned samples, I could understand most of the CMake and SCons code out of the box, so this probably isn't much of an issue.

Waf is an SCons spin-off, but it isn't available on Debian yet and I couldn't find any projects targeting Mono, that use Waf.

The ruby based build tools Rant and Rake don't have any native support for building Mono applications as well. While Rant surely is a nice tool, it seems to suffer from a lack of support. Upstream development seems to be stalled. There hasn't been a single commit in over a year. The Rake development seems to be much more active, so I would probably prefer this. Besides this I've already used Rake for small C++ toy projects and of course for Ruby projects, so I'm kinda familiar with it. But there doesn't seem to be any projects (besides IronRuby) that decided to use Rake, so I would more or less have to build everything from ground up.

There are also other interesting build tools out there (like e.g. the Boo Build System, formerly known as "Boobs"), which I simply haven't considered, just because of their low popularity. As a Debian maintainer I prefer a "grown up" and well supported build system, which is already included in the Distribution and surely other distribution maintainers do so as well. So to make distribution packaging as easy as possible, I'll stick with one of the major build tools.

Currently CMake, SCons and Autotools are on the shortlist. If I haven't missed any cool "Off Broadway" tools, it will be one of these. I'll probably give CMake and SCons a try and then decide, if one of them works well enough for my needs to avoid Autotools.

Published on 24/09/2008 at 09:56 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 , , ,

Unit test of the day

5 unit tests covering a single line of code:

[TestFixture]
public class A_SwissRounding
{
    private SwissRounding _rounding = new SwissRounding();

    [Test]
    public void Should_round_down_to_zero_when_having_zero_to_two_and_a_half()
    {
        Assert.AreEqual(1.00m, _rounding.Round(1.0010m));
        Assert.AreEqual(1.00m, _rounding.Round(1.0249m));
    }

    [Test]
    public void Should_round_up_to_five_when_having_two_and_a_half_to_five()
    {
        Assert.AreEqual(1.05m, _rounding.Round(1.0250m));
        Assert.AreEqual(1.05m, _rounding.Round(1.0490m));

    }
    [Test]
    public void Should_round_down_to_5_when_having_five_to_seven_and_a_half()
    {
        Assert.AreEqual(1.05m, _rounding.Round(1.0510m));
        Assert.AreEqual(1.05m, _rounding.Round(1.0749m));
    }

    [Test]
    public void Should_round_up_to_10_when_having_seven_and_a_half_to_ten()
    {
        Assert.AreEqual(1.10m, _rounding.Round(1.0760m));
        Assert.AreEqual(1.10m, _rounding.Round(1.0990m));
    }

    [Test]
    public void Should_not_round_multiples_of_five()
    {
        Assert.AreEqual(1.00m, _rounding.Round(1.0000m));
        Assert.AreEqual(1.05m, _rounding.Round(1.0500m));
        Assert.AreEqual(1.10m, _rounding.Round(1.1000m));
    }
}

public class SwissRounding
{
    public decimal Round(decimal value)
    {
        return Math.Round(value*20, MidpointRounding.AwayFromZero)/20;
    }
}

:-)

Published on 26/08/2008 at 18:16 by , tags , ,

Powered by Publify | Photo Startup stock photos