XNA and Ninject: Syntax for dependency arguments?
I have a class with a public constructor:
public MasterEngine(IInputReader inputReader)
{
this.inputReader = inputReader;
graphicsDeviceManager = new GraphicsDeviceManager(this);
Components.Add(new GamerServicesComponent(this));
}
How can I inject dependencies like graphicsDeviceManager
and new GamerServicesComponent
whil开发者_运维百科e still supplying the argument this
?
You should be able to inject factory delegates for the components instead of the actual components. NInject supports binding delegates out-of-the-box via its Bind<>().ToMethod()
.
The nice thing about such a construct is that you get the benefits of constructor injection while at the same time enables the instance (MasterEngine
in this case) to control when dependencies are instantiated.
Your constructor should look something like this:
public MasterEngine(IInputReader inputReader,
Func<MasterEngine,GraphicsDeviceManager> graphicsDeviceFactory,
Func<MasterEngine,GamerServicesComponent> gamerServicesFactory)
{
this.inputReader = inputReader;
graphicsDeviceManager = graphicsDeviceFactory(this);
Components.Add(gamerServicesFactory(this));
}
Here's how you bind the factory delegates, which imo is a tidier way:
Bind<Func<MasterEngine, GraphicsDeviceManager>>()
.ToMethod(context => engine => new GraphicsDeviceManager(engine));
Bind<Func<MasterEngine, GamerServicesComponent>>()
.ToMethod(context => engine => new GamerServicesComponent(engine));
This can also be done with delegate types:
public delegate GraphicsDeviceManager GdmFactory(MasterEngine engine);
public delegate GamerServicesComponent GscFactory(MasterEngine engine);
...
Bind<GdmFactory>()
.ToMethod(context => engine => new GraphicsDeviceManager(engine));
Bind<GscFactory>()
.ToMethod(context => engine => new GamerServicesComponent(engine));
...
public MasterEngine(IInputReader inputReader,
GdmFactory graphicsDeviceFactory,
GscFactory gamerServicesFactory)
{
...
}
This blog suggests one method of providing GameServices
which in turn allow things like the GraphicsDeviceManager
to be injected. I have recently implemented a project using an approach similiar to this and it worked a treat.
kernel.Bind<IInputReader>()
.To<SomeInputReader>()
.OnActivation(instance =>
{
instance.GraphicsDeviceManager = new GraphicsDeviceManager(instance);
Components.Add(new GamerServicesComponent(instance));
});
精彩评论