2010-04-06 7 views
2

Ninject와 XNA를 통합하는 데 어려움이 있습니다.Ninject를 XNA와 함께 사용하는 방법?

static class Program 
{ 
    /** 
    * The main entry point for the application. 
    */ 
    static void Main(string[] args) 
    { 
     IKernel kernel = new StandardKernel(NinjectModuleManager.GetModules()); 
     CachedContentLoader content = kernel.Get<CachedContentLoader>(); // stack overflow here 
     MasterEngine game = kernel.Get<MasterEngine>(); 
     game.Run(); 
    } 
} 

    // constructor for the game 
    public MasterEngine(IKernel kernel) 
     : base(kernel) 
    { 
     this.inputReader = kernel.Get<IInputReader>(); 

     graphicsDeviceManager = kernel.Get<GraphicsDeviceManager>(); 
     Components.Add(kernel.Get<GamerServicesComponent>()); 

     // Tell the loader to look for all files relative to the "Content" directory. 
     Assets = kernel.Get<CachedContentLoader>(); 

     //Sets dimensions of the game window 
     graphicsDeviceManager.PreferredBackBufferWidth = 800; 
     graphicsDeviceManager.PreferredBackBufferHeight = 600; 
     graphicsDeviceManager.ApplyChanges(); 

     IsMouseVisible = false; 
    } 

Ninject.cs :

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Ninject.Modules; 
using HWAlphaRelease.Controller; 
using Microsoft.Xna.Framework; 
using Nuclex.DependencyInjection.Demo.Scaffolding; 
using Microsoft.Xna.Framework.Content; 
using Microsoft.Xna.Framework.Graphics; 

namespace HWAlphaRelease 
{ 
    public static class NinjectModuleManager 
    { 

     public static NinjectModule[] GetModules() 
     { 
      return new NinjectModule[1] { new GameModule() }; 
     } 

     /// <summary>Dependency injection rules for the main game instance</summary> 
     public class GameModule : NinjectModule 
     { 

      #region class ServiceProviderAdapter 

      /// <summary>Delegates to the game's built-in service provider</summary> 
      /// <remarks> 
      /// <para> 
      ///  When a class' constructor requires an IServiceProvider, the dependency 
      ///  injector cannot just construct a new one and wouldn't know that it has 
      ///  to create an instance of the Game class (or take it from the existing 
      ///  Game instance). 
      /// </para> 
      /// <para> 
      ///  The solution, then, is this small adapter that takes a Game instance 
      ///  and acts as if it was a freely constructable IServiceProvider implementation 
      ///  while in reality, it delegates all lookups to the Game's service container. 
      /// </para> 
      /// </remarks> 
      private class ServiceProviderAdapter : IServiceProvider 
      { 

       /// <summary>Initializes a new service provider adapter for the game</summary> 
       /// <param name="game">Game the service provider will be taken from</param> 
       public ServiceProviderAdapter(Game game) 
       { 
        this.gameServices = game.Services; 
       } 

       /// <summary>Retrieves a service from the game service container</summary> 
       /// <param name="serviceType">Type of the service that will be retrieved</param> 
       /// <returns>The service that has been requested</returns> 
       public object GetService(Type serviceType) 
       { 
        return this.gameServices; 
       } 

       /// <summary>Game services container of the Game instance</summary> 
       private GameServiceContainer gameServices; 

      } 

      #endregion // class ServiceProviderAdapter 

      #region class ContentManagerAdapter 

      /// <summary>Delegates to the game's built-in ContentManager</summary> 
      /// <remarks> 
      /// This provides shared access to the game's ContentManager. A dependency 
      /// injected class only needs to require the ISharedContentService in its 
      /// constructor and the dependency injector will automatically resolve it 
      /// to this adapter, which delegates to the Game's built-in content manager. 
      /// </remarks> 
      private class ContentManagerAdapter : ISharedContentService 
      { 

       /// <summary>Initializes a new shared content manager adapter</summary> 
       /// <param name="game">Game the content manager will be taken from</param> 
       public ContentManagerAdapter(Game game) 
       { 
        this.contentManager = game.Content; 
       } 

       /// <summary>Loads or accesses shared game content</summary> 
       /// <typeparam name="AssetType">Type of the asset to be loaded or accessed</typeparam> 
       /// <param name="assetName">Path and name of the requested asset</param> 
       /// <returns>The requested asset from the the shared game content store</returns> 
       public AssetType Load<AssetType>(string assetName) 
       { 
        return this.contentManager.Load<AssetType>(assetName); 
       } 

       /// <summary>The content manager this instance delegates to</summary> 
       private ContentManager contentManager; 

      } 

      #endregion // class ContentManagerAdapter 

      /// <summary>Initializes the dependency configuration</summary> 
      public override void Load() 
      { 

       // Allows access to the game class for any components with a dependency 
       // on the 'Game' or 'DependencyInjectionGame' classes. 
       Bind<MasterEngine>().ToSelf().InSingletonScope(); 
       Bind<NinjectGame>().To<MasterEngine>().InSingletonScope(); 
       Bind<Game>().To<MasterEngine>().InSingletonScope(); 

       // Let the dependency injector construct a graphics device manager for 
       // all components depending on the IGraphicsDeviceService and 
       // IGraphicsDeviceManager interfaces 
       Bind<GraphicsDeviceManager>().ToSelf().InSingletonScope(); 
       Bind<IGraphicsDeviceService>().To<GraphicsDeviceManager>().InSingletonScope(); 
       Bind<IGraphicsDeviceManager>().To<GraphicsDeviceManager>().InSingletonScope(); 

       // Some clever adapters that hand out the Game's IServiceProvider and allow 
       // access to its built-in ContentManager 
       Bind<IServiceProvider>().To<ServiceProviderAdapter>().InSingletonScope(); 
       Bind<ISharedContentService>().To<ContentManagerAdapter>().InSingletonScope(); 

       Bind<IInputReader>().To<UserInputReader>().InSingletonScope().WithConstructorArgument("keyMapping", Constants.DEFAULT_KEY_MAPPING); 
       Bind<CachedContentLoader>().ToSelf().InSingletonScope().WithConstructorArgument("rootDir", "Content"); 

      } 

     } 

    } 

} 

NinjectGame.cs

/// <summary>Base class for Games making use of Ninject</summary> 
    public class NinjectGame : Game { 

    /// <summary>Initializes a new Ninject game instance</summary> 
    /// <param name="kernel">Kernel the game has been created by</param> 
    public NinjectGame(IKernel kernel) { 
     Type ownType = this.GetType(); 

     if(ownType != typeof(Game)) { 
     kernel.Bind<NinjectGame>().To<MasterEngine>().InSingletonScope(); 
     } 

     kernel.Bind<Game>().To<NinjectGame>().InSingletonScope(); 
    } 

    } 

} // namespace Nuclex.DependencyInjection.Demo.Scaffolding 

나는 CachedContentLoader을 얻으려고, 내가 스택 오버 플로우 예외를 얻을. 나는 이것을 tutorial에서 벗어나고있다. 그러나 나는 정말로 내가 무엇을하고 있는지 전혀 모른다. 도움?

답변

0

구성된 종속성 중 하나에 순환 참조가있을 수 있습니다. 그래서 ninject가 문제의 클래스를 인스턴스화하려고하면 끝없는 반복 루프가됩니다.

나는 당신의 수업을 들여다 보지 않았지만 GameModule.Load에서 정의한 각 클래스의 생성자에 중단 점을 두는 것이 좋습니다. 중첩 된 인스턴스화가 어디에서 발생하는지 알게되면 바로 알기 쉽습니다.

관련 문제