For my international reader, a bit of context is in order for this post: Microsoft Denmark sponsors a series of Christmas challenges known as the Microsoft Christmas Calendar. Different bloggers alternate hosting a coding challenge for the day, and Microsoft sponsors the prizes.
Today I have the honor of hosting the last challenge for 2010. Contestants from the Danish .NET community have the opportunity to win a Molecular Gastronomy Starter Kit – if any of my international readers feel like joining in, they are welcome, but (probably) not eligible for the prize.
The challenge
The Managed Extensibility Framework (MEF) enables us to compose applications by annotating types and members with [Import] and [Export] attributes, but what can you do when you have types without these attributes and you can’t add the attributes?
For example, how can we compose Mayonnaise from these three classes?
public sealed class EggYolk { }
public sealed class OliveOil { }
public sealed class Mayonnaise
{
private readonly EggYolk eggYolk;
private readonly OliveOil oil;
public Mayonnaise(EggYolk eggYolk, OliveOil oil)
if (eggYolk == null)
throw new ArgumentNullException("eggYolk");
}
if (oil == null)
throw new ArgumentNullException("oil");
this.eggYolk = eggYolk;
this.oil = oil;
public EggYolk EggYolk
get { return this.eggYolk; }
public OliveOil Oil
get { return this.oil; }
The challenge is to come up with a good solution to that problem. Here are the formal rules:
There are lots of different ways to skin this cat, so I’m looking forward to your submissions to see all your creative solutions.
This unit test suite is the specification:
using System.ComponentModel.Composition.Hosting;
using Ploeh.Samples.MeffyXmas.MenuModel;
using Xunit;
namespace Ploeh.Samples.MeffyXmas.MefMenu.UnitTest
public class ContainerBuilderFacts
[Fact]
public void DefaultContainerCorrectlyResolvesOliveOil()
CompositionContainer container = new ContainerBuilder()
.Build();
var oil = container.GetExportedValue<OliveOil>();
Assert.NotNull(oil);
public void DefaultContainerCorrectlyResolvesEggYolk()
var yolk = container.GetExportedValue<EggYolk>();
Assert.NotNull(yolk);
public void DefaultContainerCorrectlyResolvesMayonnaise()
var mayo = container.GetExportedValue<Mayonnaise>();
Assert.NotNull(mayo);
public void DefaultContainerReturnsSingletonMayonnaise()
var mayo1 = container.GetExportedValue<Mayonnaise>();
var mayo2 = container.GetExportedValue<Mayonnaise>();
Assert.Same(mayo1, mayo2);
public void WithTransientMayonnaiseReturnTransientMayonnaise()
.WithNonSharedMayonnaise()
Assert.NotSame(mayo1, mayo2);
public void TransientMayonnaiseByDefaultContainsSingletonEggYolk()
Assert.Same(mayo1.EggYolk, mayo2.EggYolk);
public void TransientMayonnaiseByDefaultContainsSingletonOil()
Assert.Same(mayo1.Oil, mayo2.Oil);
public void TransientMayonnaiseCanHaveTransientEggYolk()
.WithNonSharedEggYolk()
Assert.NotSame(mayo1.EggYolk, mayo2.EggYolk);
public void TransientMayonnaiseCanHaveSingletonOil()
public void TransientMayonnaiseCanHaveTransientOil()
.WithNonSharedOil()
Assert.NotSame(mayo1.Oil, mayo2.Oil);
public void TransientMayonnaiseCanHaveSingletonEggYolk()
public void PureTransientMayonnaiseIsTransient()
public void PureTransientMayonnaiseHasTransientEggYolk()
public void PureTransientMayonnaiseHasTransientOil()
ContainerBuilder is the class you must implement, so the unit tests don’t compile until you make them. Meffy xmas!
Remember Me
a@href@title, b, em, i, strike, strong
Page rendered at Thursday, February 23, 2012 4:56:00 AM (Romance Standard Time, UTC+01:00)
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.