我一直在使用Ninject作为XNA项目的IOC,并希望将其迁移到Ninject 2.0。但是,XNA不是依赖注入友好的,因为某些类必须在游戏类的构造函数中实例化,但必须将游戏类传递给它们的构造函数。例如:
public MyGame ()
{
this.graphicsDeviceManager = new GraphicsDeviceManager (this);
}
文章here描述了一种解决方法,其中明确告知IOC容器用于解析服务的实例。
/// <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);
}
但是,我不确定如何在Ninject 2.0中实现这一点,因为我认为是等效的代码
if (type != typeof (Game))
{
kernel.Bind (type).ToConstant (this).InSingletonScope ();
}
kernel.Bind (typeof (Game)).ToConstant (this).InSingletonScope ();
kernel.Bind (typeof (NinjectGame)).ToConstant (this).InSingletonScope ();
仍会产生StackOverflowException
。任何关于至少从哪里开始的想法都将不胜感激。
答案 0 :(得分:2)
如果再次调用MyGame
,问题似乎来自Ninject不会自动替换之前在NinjectGame
,Game
和Bind()
之间设置的绑定。解决方案是再次调用Unbind()
,然后调用Bind()
,或者只调用Rebind()
,这是我选择做的事情
if (type != typeof (Game))
{
kernel.Rebind (type).ToConstant (this).InSingletonScope ();
}
kernel.Rebind (typeof (Game)).ToConstant (this).InSingletonScope ();
kernel.Rebind (typeof (NinjectGame)).ToConstant (this).InSingletonScope ();
因为如果在调用之前不存在绑定,它不会抛出异常或引起任何其他问题。