使用Ninject 2.0避免XNA中的循环依赖问题

3

我一直在一个XNA项目中使用Ninject作为IOC容器,现在想将其迁移到Ninject 2.0。然而,XNA并不友好地支持依赖注入,因为某些类必须在游戏类的构造函数中实例化,但同时也必须将游戏类传递给它们的构造函数。例如:

public MyGame ()
{
    this.graphicsDeviceManager = new GraphicsDeviceManager (this);
}

这篇文章讲述了一种解决方法,其中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。如果有任何想法至少在哪里继续,请告诉我们。


去下载源代码的主干。这只需要2分钟。然后看看测试——它们提供了简短明了的语法示例。然后你就能在比发帖所花费的时间更短的时间内回答这个问题了(真的)。 - Ruben Bartelink
1个回答

2

看起来问题是由于Ninject没有自动替换之前在MyGameNinjectGameGame之间建立的绑定,如果再次调用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 ();

由于调用之前不存在绑定不会引发异常或导致其他问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接