2010-06-30 17 views
3

J'ai utilisé Ninject comme IOC pour un projet XNA, et je voulais le migrer vers Ninject 2.0. Cependant, XNA n'est pas favorable à l'injection de dépendances, car certaines classes doivent être instanciées dans le constructeur de la classe de jeu, mais doivent également transmettre la classe de jeu à leurs constructeurs. Par exemple:Éviter les dépendances circulaires dans XNA en utilisant Ninject 2.0

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

Un article here décrit un travail autour, où le conteneur du CIO est explicitement informé de ce cas à utiliser pour résoudre le service.

/// <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); 
} 

Cependant, je suis incertain quant à la façon d'y arriver dans Ninject 2.0, comme ce que je pense est le code équivalent

if (type != typeof (Game)) 
{ 
    kernel.Bind (type).ToConstant (this).InSingletonScope(); 
} 
kernel.Bind (typeof (Game)).ToConstant (this).InSingletonScope(); 
kernel.Bind (typeof (NinjectGame)).ToConstant (this).InSingletonScope(); 

produit encore StackOverflowException. Toute idée sur au moins où aller d'ici serait appréciée.

+0

Allez télécharger le coffre de la source. Cela prendra 2 minutes. Regardez ensuite dans les tests - ils fournissent des exemples clairs de syntaxe. Ensuite, vous serez en mesure de répondre à cela en moins de temps qu'il ne vous a fallu pour poster ceci (Sérieusement) –

Répondre

2

Il semblerait que le problème vient de Ninject pas remplacer automatiquement les liaisons qui ont été définies précédemment entre MyGame, NinjectGame et Game si Bind() est appelé à nouveau. La solution est d'appeler soit Unbind(), puis Bind() à nouveau, ou tout simplement d'appeler Rebind(), qui est ce que j'ai choisi de faire

if (type != typeof (Game)) 
{ 
    kernel.Rebind (type).ToConstant (this).InSingletonScope(); 
} 
kernel.Rebind (typeof (Game)).ToConstant (this).InSingletonScope(); 
kernel.Rebind (typeof (NinjectGame)).ToConstant (this).InSingletonScope(); 

car il ne lancera pas d'exception ou de causer d'autres problèmes si la liaison n'existait avant son appel.