Trying to integrate Ninject with XNA however I am having a bit of pain trying to get it all hooked up.
The problem is I am trying to do it as I think it should done, so I am decoupling things as much as possible to make it more modular, and Xna isn't happy with me doing this... an example of this is where the Game object news up a lot of things internally, and a lot of those things could do with being passed around to my objects. So I decided to add these as constructor arguments to the Game class, so I can setup all the dependencies then use Ninject to give me the Game instance with all its dependencies resolved.
Unfortunately In this example normally XNA doesn't new up its SpriteBatch until it has gotten to the Initilize stage, which I assume is because it needs the GraphicsDeviceManager to get the window handle to create the GraphicsDevice before it can be exposed for anything to use...
So because of this they cannot be injected into the game because it needs to do its stuff first, and I cannot really push them in after the game is made, because I need other things like the World component to be injected with things as well and pushed into the game.
At this point I thought maybe I could create my own GraphicsDevice, but as I need the handle I would need to make my own window too, which I later realised XNA would dispose and recreate anyway. So it leaves me with a horrible taste in my mouth... as I dont fancy re-writing the Game and GraphicsDeviceManager classes, which would require me to re-write lots of other functionality as they are all internal to the XNA assembly...
So has anyone managed to setup their dependency injection without having to re-write large chunks of XNA?
Here is an example of my current module:
public class XnaModule : NinjectModule
{
public override void Load()
{
Kernel.Bind<IServiceProvider>().To<NinjectServiceProvider>().InSingletonScope();
Kernel.Bind<IGraphicsDeviceService>().To<GraphicsDeviceManager>().InSingletonScope();
Kernel.Bind<ContentManager>().ToSelf().InSingletonScope();
Kernel.Bind<SpriteBatch>().ToSelf().InSingletonScope();
var contentManager = new ContentManager(Kernel.Get<IServiceProvider>());
contentManager.RootDirectory = "Content";
Kernel.Bind<ContentManager>().ToConstant(contentManager).InSingletonScope();
var game = new MyGame(Kernel.Get<IGraphicsDeviceService>() as GraphicsDeviceManager,
Kernel.Get<SpriteBatch>(), contentManager);
Kernel.Bind<Game>().ToConstant(game).InSingletonScope();
}
}
Then the game constructor:
public class MyGame : Game
{
public SpriteBatch SpriteBatch { get; private set; }
public GraphicsDeviceManager Graphics { get; private set; }
public MyGame(GraphicsDeviceManager graphics, SpriteBatch spriteBatch, ContentManager contentManager)
{
Graphics = graphics;
SpriteBatch = spriteBatch;
Content = contentManager;
}
// Other stuffs
}
Both are just examples so you can see the sort of approach I am taking, the module bypasses the circular dependency issue as I new the game up myself. And I have excluded the GameModule, which would contain the dependencies for my actual Game objects, i.e factories, gui components etc, and the problem is they ultimately need to be injected into the Game too, and we then we have a catch22.
As they cannot be injected until the dependencies are resolved, but you cannot resolve the dependencies until you have started the game... it seems a lose/lose situation. So can anyone tell me how they got round this issue?
I did find http://steveproxna01di.codeplex.com/ but was looking if there are any more examples as this is more of a service locator approach, rather than an Injection approach.