views:

82

answers:

1

I am experiencing an issue with v1 of Ninject and resetting the StandardKernel. I have a static object that I use to provide access to the kernel like so

public static class ObjectFactory
{
    private static IKernel _kernel =  new StandardKernel(new CanceisModule());

    // Resolve methods snipped for brevity

    public static void Reset()
    {
        _kernel = null;
        _kernel = new StandardKernel(new CanceisModule());
    }
}

The problem comes when I try to use ObjectFactory in various unit tests (I use MSTest) or fitnesse fixtures. I always call the ObjectFactory.Reset() method before every new test or fixture but sometimes it seems like the Reset doesn't actually work and leaves the original bindings in place. I know there is a way to reset the IKernel objects in v2 of Ninject but we aren't ready to make that move yet (and its a fairly significant move for us).

Could someone offer some advice on why this might be occuring? I'm guessing that it is related to the way tests are executed on separate threads in the different runners but how do I avoid it?

Thanks in advance

A: 

Your approach seems fine.

In general, test runners don't run multi threaded or anything magic like you're guessing.

I'd suggest putting a breakpoint in your Reset() and debugging your tests.

Your code has a non-static method in a static class so is there something else you're omitting to mention?

When you say "new test or fixture", which is it? Often it you are using Ninject in tests, it's better to keep a kernel in a base class and make sure it's reset at the right time to avoid any confusion or doubt [rather than relying on an object factory 'singleton'].

Ruben Bartelink
The non-static Reset was a typo (no internet at my desk so I have to copy as best I can). When I debug the tests (either MSTest or Fitnesse the behavior occurs in both) the Reset method always works. That's what is so perplexing.When I say "new test or fixture" I mean it happens in either case. In Fixtures I always call ObjectFactory.Reset in the constructor of the fixture itself. In MSTest, I have a base class that every other class derives from that calls ObjectFactory.Reset() before every test using the [TestInitialize] attributed method.Any other guesses?
Jeffrey Cameron
Is it that just releasing the reference [like you do in Reset()] to the old Kernel doesnt trigger the disposing (and finalisation) of the objects at the right point? If you're relying on cleanup to remove links to shared objects etc., this may be delayed until GC time. I'm no MSTest expert but TestInitialize seems the safest default place to put it (for isolation reasons). Bottom line: Neither select nor the test framework is broken - chances are there's somethign in your objects as they live in the Module that means that they're not cleaning themselves up properly.
Ruben Bartelink
Haviong said that, for me all this confusion of what does and doesnt go on in startup in NUnit and MSTest goes away in xUnit.net. I'm sorry I wasted so much of my life tracing convoluted hierarchies of test initialization.
Ruben Bartelink
Thanks for the advice Ruben. I think I may end up witching to xUnit ... it is so much cleaner and easier to work with
Jeffrey Cameron