Предотвращение циклических зависимостей в XNA с использованием Ninject 2.0

#dependency-injection #xna #ninject #ninject-2

#внедрение зависимостей #xna #ninject #ninject-2

Вопрос:

Я использовал Ninject в качестве IOC для проекта XNA и хотел перенести его на Ninject 2.0. Однако XNA не поддерживает внедрение зависимостей, поскольку определенные классы должны создаваться в конструкторе класса game, но также должны передавать класс game своим конструкторам. Например:

 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 минуты. Затем загляните в тесты — они предоставляют короткие четкие примеры синтаксиса. Тогда вы сможете ответить на этот вопрос за меньшее время, чем потребовалось вам для публикации этого (серьезно)

Ответ №1:

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

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