views:

311

answers:

2

I'm writing some unit tests that rely on StructureMap so I want to completely reset the ObjectFactory in my [SetUp] method. This is what my [SetUp] method looks like right now:

[SetUp]
public void SetUp()
{
    ObjectFactory.Initialize(initializationExpression => {});
}

This appears to reset the configuration because I can execute the ObjectFactory.WhatDoIHave() method and it does not contain any of my configuration. However, cached instances of objects are not removed and are returned in subsequent tests. Is there a way to completely reset the ObjectFactory?

I thought I might have to use ObjectFactory.EjectAllInstancesOf(), but that doesn't appear to help.

I'm using version 2.5.3.

Here is some contrived code to show what I'm talking about. I would expect this test to pass, but it doesn't.

[TestFixture]
public class TestingStructureMap
{
    [Test]
    public void FirstTestUsingCachedObjects()
    {
        ObjectFactory.Configure(configure =>
            configure.ForRequestedType<ISomeInterface>()
                .TheDefaultIsConcreteType<SomeImplementation>()
                .CacheBy(InstanceScope.ThreadLocal)
            );

        ISomeInterface firstSomeInterface = ObjectFactory.GetInstance<ISomeInterface>();
        Assert.AreEqual(1, firstSomeInterface.ID);

        ObjectFactory.Initialize(initializationExpression => { });
        ObjectFactory.EjectAllInstancesOf<ISomeInterface>();

        ObjectFactory.Configure(configure =>
            configure.ForRequestedType<ISomeInterface>()
                .TheDefaultIsConcreteType<SomeImplementation>()
                .CacheBy(InstanceScope.ThreadLocal)
            );

        ISomeInterface secondSomeInterface = ObjectFactory.GetInstance<ISomeInterface>();
        Assert.AreEqual(2, secondSomeInterface.ID);
    }

    public interface ISomeInterface
    {
        int ID { get; }
    }

    public class SomeImplementation : ISomeInterface
    {
        private static int NumberOfInstancesCreated;
        private readonly int id;

        public int ID
        {
            get { return id; }
        }

        public SomeImplementation()
        {
            id = ++NumberOfInstancesCreated;
        }
    }
}
A: 

Not exactly an answer but to have you considered wrinting your test such that you do not rely on the ObjectFactory but the StructureMap container?

var c = new StructureMap.Container(ce=>
       {
          ce.ForRequestedType<IFoo>().TheDefaultIsConcreteType<Bar>();
       });

In that case you can simply recreate the container and my guess is that it should be in pristine condition.

flq
I modified the test I posted above to use the container instead and it still fails.
Stefan Moser
Recreating the container is pretty darned slow though ...
Andrew
A: 

I've figured it out. ObjectFactory.EjectAllInstancesOf() is actually dependant on there being a configuration for T. In my code, I nullified the effectiveness of ObjectFactory.EjectAllInstancesOf() by first clearing all of the configuration. If I swith these two lines of code, it works.

This does NOT work:

ObjectFactory.Initialize(initializationExpression => { });
ObjectFactory.EjectAllInstancesOf<ISomeInterface>();

This DOES work:

ObjectFactory.EjectAllInstancesOf<ISomeInterface>();
ObjectFactory.Initialize(initializationExpression => { });
Stefan Moser