Как избежать циклических зависимостей в XNA с помощью Ninject 2.0 - PullRequest
3 голосов
/ 30 июня 2010

Я использовал Ninject в качестве IOC для проекта XNA и хотел перенести его на 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. Будем благодарны за любые мысли, по крайней мере, куда идти дальше.

1 Ответ

2 голосов
/ 02 июля 2010

Может показаться, что проблема связана с тем, что Ninject не заменяет автоматически привязки, которые были установлены ранее между MyGame, 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 ();

, так как это не вызовет исключения или не вызовет какую-либодругие проблемы, если привязка не существовала до ее вызова.

...