开发者

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));
                                    });
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜