views:

46

answers:

1

I have been using Ninject as the IOC for an XNA project, and was wanting to migrate it to Ninject 2.0. However, XNA is not dependency injection friendly, as certain classes must be instantiated in the constructor of the game class, but must pass the game class to their constructors as well. For example:

public MyGame ()
{
    this.graphicsDeviceManager = new GraphicsDeviceManager (this);
}

An article here describes one work-around, where the IOC container is explicitly informed of what instance to use to resolve the service.

/// <summary>Initializes a new Ninject game instance</summary>
/// <param name="kernel">Kernel the game has been created by</param>
public NinjectGame (IKernel kernel)
{
    Type type = this.GetType ();

    if (type != typeof (Game))
    {
        this.bindToThis (kernel, type);
    }
    this.bindToThis (kernel, typeof (Game));
    this.bindToThis (kernel, typeof (NinjectGame));
}

/// <summary>Binds the provided type to this instance</summary>
/// <param name="kernel">Kernel the binding will be registered to</param>
/// <param name="serviceType">Service to which this instance will be bound</param>
private void bindToThis (IKernel kernel, Type serviceType)
{
    StandardBinding binding = new StandardBinding (kernel, serviceType);
    IBindingTargetSyntax binder = new StandardBinder (binding);

    binder.ToConstant (this);
    kernel.AddBinding (binding);
}

However, I'm uncertain as to how to accomplish this in Ninject 2.0, as what I would think is the equivalent code

if (type != typeof (Game))
{
    kernel.Bind (type).ToConstant (this).InSingletonScope ();
}
kernel.Bind (typeof (Game)).ToConstant (this).InSingletonScope ();
kernel.Bind (typeof (NinjectGame)).ToConstant (this).InSingletonScope ();

still produces a StackOverflowException. Any thoughts on at least where to proceed from here would be appreciated.

A: 

It would appear that the problem comes from Ninject not automatically replacing the bindings that were set earlier between MyGame, NinjectGame and Game if Bind() is called again. The solution is to call either Unbind(), then Bind() again, or just to call Rebind(), which is what I chose to do

if (type != typeof (Game))
{
    kernel.Rebind (type).ToConstant (this).InSingletonScope ();
}
kernel.Rebind (typeof (Game)).ToConstant (this).InSingletonScope ();
kernel.Rebind (typeof (NinjectGame)).ToConstant (this).InSingletonScope ();

since it will not throw an exception or cause any other problems if a binding did not exist prior to its call.

johaanfaust