Puzzle: IoC container for WinRT
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