1

I'm using StructureMap and trying to register a temporary implementation for an interface (a stub).

After reading this article I came up with the following setup:

The definition of the interface:

public interface IConsoleWriter
{
    void Write(string message);
}

The regular implementation:

public class ConsoleWriter : IConsoleWriter
{
    public void Write(string message)
    {
        Console.WriteLine("That's the message: '{0}'", message);
    }
}

The fake implementation:

public class FakeConsoleWriter : IConsoleWriter
{
    public void Write(string message)
    {
        Console.WriteLine("That's a fake writer who does not care about your message.");
    }
}

Now, having all these defined, I use the following scenario:

    static void TestTemporaryStub()
    {
        // register the regular implementation as default
        ObjectFactory.Initialize(x => x.For<IConsoleWriter>().Use<ConsoleWriter>());

        var writer1 = ObjectFactory.GetInstance<IConsoleWriter>();
        writer1.Write("abc");

        // temporarily inject a fake implementation
        ObjectFactory.Inject(typeof(IConsoleWriter), new FakeConsoleWriter());

        var writer2 = ObjectFactory.GetInstance<IConsoleWriter>();
        writer2.Write("abc");

        // attempt to reset the settings to default
        ObjectFactory.ResetDefaults();

        var writer3 = ObjectFactory.GetInstance<IConsoleWriter>();
        writer3.Write("abc");
    }

In the code above, I ask the StructureMap container to retrieve an IConsoleWriter imnplementation three times:

  1. After the container has been initialized to use the regular implementation - it returns the regular implementation -> Ok.
  2. After injecting the fake implementation -> it returns the fake implementation -> Ok.
  3. After reverting back to the defaults -> should return the regular implementation (ConsoleWriter), but it still returns the fake -> Not Ok.

Am I missing something in here?

Cristian Lupascu
  • 39,078
  • 16
  • 100
  • 137
  • 1
    Since you want to replace a dependency with a Stub, I'm assuming that you want to write a unit test. If this is, indeed, the case, you'd be better off not using the container for unit testing at all: http://stackoverflow.com/questions/1465849/using-ioc-for-unit-testing/1465896#1465896 – Mark Seemann Sep 13 '11 at 12:05
  • You are right. I just saw that it's documented to work this way and it seemed like the the easiest thing to do in a given scenario. If I need to have a container (e.g. integration tests) then I'd probably be better off just using a completely different container, built specifically for that, instead of trying to patch the existing container. – Cristian Lupascu Sep 13 '11 at 12:16
  • I believe this method was one of the first steps integrating unit-tests and mocks/stubs. It's primarily used when not autowiring the whole objectgraph but directly getting objects from ObjectFactory or using a ServiceLocator (which are also anti-patterns). A better way, alternatively to Mark Seemanns, could be the use of Structuremap as automocker. – Jan Christian Selke Sep 13 '11 at 12:46
  • Exactly the same problem here. – Martin R-L Apr 25 '12 at 14:52
  • I added my reproducing code in a gist: https://gist.github.com/2492561 – Martin R-L Apr 26 '12 at 06:25
  • @MartinR-L please see Mark's comment and link - it's best to avoid using containers in Unit Tests – Cristian Lupascu Apr 26 '12 at 08:46
  • That comment doesn't help at all w0lf. I had already read Mark's comment before you told me to. Heck, I even own his book and have met him in person several times ;-) Sometimes you're working with brownfield development, and just want a feature of the used container to work without getting lectured about it... – Martin R-L Apr 26 '12 at 20:56

0 Answers0