我有一个带有公共构造函数的类:
public MasterEngine(IInputReader inputReader)
{
this.inputReader = inputReader;
graphicsDeviceManager = new GraphicsDeviceManager(this);
Components.Add(new GamerServicesComponent(this));
}
如何在仍然提供参数graphicsDeviceManager
的同时注入new GamerServicesComponent
和this
等依赖项?
答案 0 :(得分:3)
您应该能够为组件而不是实际组件注入工厂代理。 NInject通过其Bind<>().ToMethod()
支持绑定代表开箱即用。
这样一个构造的好处是你可以获得构造函数注入的好处,同时使实例(在这种情况下为MasterEngine
)能够在实例化依赖项时控制 。
你的构造函数应该是这样的:
public MasterEngine(IInputReader inputReader,
Func<MasterEngine,GraphicsDeviceManager> graphicsDeviceFactory,
Func<MasterEngine,GamerServicesComponent> gamerServicesFactory)
{
this.inputReader = inputReader;
graphicsDeviceManager = graphicsDeviceFactory(this);
Components.Add(gamerServicesFactory(this));
}
以下是绑定工厂代理的方式,这是一种更整洁的方式:
Bind<Func<MasterEngine, GraphicsDeviceManager>>()
.ToMethod(context => engine => new GraphicsDeviceManager(engine));
Bind<Func<MasterEngine, GamerServicesComponent>>()
.ToMethod(context => engine => new GamerServicesComponent(engine));
这也可以使用委托类型来完成:
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)
{
...
}
答案 1 :(得分:1)
这个blog提出了一种提供GameServices
的方法,这种方法又允许注入GraphicsDeviceManager
之类的内容。我最近使用类似于此的方法实现了一个项目,并且它起了作用。
答案 2 :(得分:0)
kernel.Bind<IInputReader>()
.To<SomeInputReader>()
.OnActivation(instance =>
{
instance.GraphicsDeviceManager = new GraphicsDeviceManager(instance);
Components.Add(new GamerServicesComponent(instance));
});