I’ve just finished reading a post (in Italian) from my friend, and former and new colleague, Matteo where, speaking about navigation in Metro applications, he introduces an inversion of control container called Metroioc.

I would like to let my readers know that Radical provides its own inversion of control container, and it’s called Puzzle. We have decided to give its API a shape really similar to the one provided by Castle Windsor, so you have entries, facilities and installers.

You can find a pre release version on NuGet:

How to

Setting up the container is really easy:

[TestMethod]
public void puzzleContainer_register_entry_using_valid_entry_should_not_fail()
{
    var container = new PuzzleContainer();
    container.Register( EntryBuilder.For<String>() );
}

Or:

[TestMethod]
public void puzzleContainer_register_entry_using_instance_should_resolve_the_given_instance()
{
    var expected = new Object();

    var container = new PuzzleContainer();

    container.Register( EntryBuilder.For<Object>().UsingInstance( expected ) );
    var actual = container.Resolve<Object>();

    Assert.AreEqual( expected, actual );
}

There are all the typical expected option on the entry builder, such as ImplementedBy<T> or the lifestyle management API:

[TestMethod]
public void puzzleContainer_register_entry_as_transient_should_resolve_instances_as_transient()
{
    var container = new PuzzleContainer();

    container.Register( EntryBuilder.For<Object>().WithLifestyle( Lifestyle.Transient ) );
    var i1 = container.Resolve<Object>();
    var i2 = container.Resolve<Object>();

    Assert.AreNotEqual( i1, i2 );
}

And obviously the ability to use a factory to build type instances:

[TestMethod]
public void puzzleContainer_register_entry_with_factory_as_transient_should_resolve_instances_as_transient()
{
    var expected = 2;
    var actual = 0;
    var container = new PuzzleContainer();

    container.Register
    (
        EntryBuilder.For<Object>()
            .UsingFactory( () =>
            {
                actual++;
                return new Object();
            } )
            .WithLifestyle( Lifestyle.Transient )
    );

    container.Resolve<Object>();
    container.Resolve<Object>();

    Assert.AreEqual( expected, actual );
}

Obviously you can even benefit of the “installer” concept: IPuzzleSetupDescriptor:

public interface IPuzzleSetupDescriptor
{
    Task Setup( IPuzzleContainer container, Func<IEnumerable<TypeInfo>> knownTypesProvider );
}

it is just a simple way to wire up stuff at boot time, just provide a set classes that implements the interface and call the:

async Task SetupWith( Func<IEnumerable<TypeInfo>> knownTypesProvider, params IPuzzleSetupDescriptor[] descriptors )

method of the container, as you can see everything is defined to work with the async/await new keywords.

We’ll speak about the knownTypesProvider when we introduce the Metro application bootstrapper.

.m