#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 ();
поскольку это не вызовет исключения или каких-либо других проблем, если привязка не существовала до ее вызова.