Интеграция Ninject с Xna 4.0 - PullRequest
       6

Интеграция Ninject с Xna 4.0

3 голосов
/ 21 января 2012

Я пытаюсь интегрировать Ninject с XNA, но мне немного больно, пытаясь все это подключить.

Проблема в том, что я пытаюсь сделать это так, как я думаю, должно сделать, поэтому я делаю все возможное, чтобы сделать его более модульным, и Xna не довольна тем, как я это делаю ... Примером этого является то, что объект Game сообщает о многих вещах изнутри, и многие из этих вещей могут быть связаны с передачей моим объектам. Поэтому я решил добавить их в качестве аргументов конструктора в класс Game, чтобы я мог настроить все зависимости и затем использовать Ninject, чтобы предоставить мне экземпляр Game со всеми разрешенными зависимостями.

К сожалению, в этом примере обычно XNA не обновляет свой SpriteBatch до тех пор, пока он не достиг стадии инициализации, что, как я полагаю, связано с тем, что ему нужен GraphicsDeviceManager, чтобы получить дескриптор окна для создания GraphicsDevice, прежде чем его можно будет открыть для чего-либо использовать ...

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

В этот момент я подумал, что, возможно, я смогу создать свой собственный GraphicsDevice, но, поскольку мне нужен дескриптор, мне нужно будет также создать свое собственное окно, которое я позже понял, что XNA все равно будет располагать и воссоздавать. Так что это оставляет у меня ужасный вкус во рту ... поскольку мне не хочется переписывать классы Game и GraphicsDeviceManager, что потребовало бы от меня переписать множество других функций, поскольку все они являются внутренними для сборки XNA ... .

Так кому-нибудь удалось настроить внедрение своих зависимостей без необходимости перезаписывать большие фрагменты XNA?

Вот пример моего текущего модуля:

public class XnaModule : NinjectModule
{
    public override void Load()
    {
        Kernel.Bind<IServiceProvider>().To<NinjectServiceProvider>().InSingletonScope();
        Kernel.Bind<IGraphicsDeviceService>().To<GraphicsDeviceManager>().InSingletonScope();
        Kernel.Bind<ContentManager>().ToSelf().InSingletonScope();
        Kernel.Bind<SpriteBatch>().ToSelf().InSingletonScope();

        var contentManager = new ContentManager(Kernel.Get<IServiceProvider>());
        contentManager.RootDirectory = "Content";
        Kernel.Bind<ContentManager>().ToConstant(contentManager).InSingletonScope();

        var game = new MyGame(Kernel.Get<IGraphicsDeviceService>() as GraphicsDeviceManager,
                                    Kernel.Get<SpriteBatch>(), contentManager);
        Kernel.Bind<Game>().ToConstant(game).InSingletonScope();
    }
}

Тогда конструктор игры:

public class MyGame : Game
{
    public SpriteBatch SpriteBatch { get; private set; }
    public GraphicsDeviceManager Graphics { get; private set; }

    public MyGame(GraphicsDeviceManager graphics, SpriteBatch spriteBatch, ContentManager contentManager)
    {
        Graphics = graphics;
        SpriteBatch = spriteBatch;
        Content = contentManager;
    }

    // Other stuffs
}

Оба примера являются лишь примерами, поэтому вы можете увидеть подход, который я использую: модуль обходит проблему циклических зависимостей, когда я сам запускаю игру. И я исключил GameModule, который содержал бы зависимости для моих реальных игровых объектов, то есть фабрик, компонентов графического интерфейса и т. Д., И проблема в том, что их в конечном итоге тоже нужно вводить в игру, и тогда у нас будет ловушка22.

Поскольку они не могут быть введены, пока не разрешены зависимости, но вы не можете разрешить зависимости, пока не запустили игру ... похоже ситуация проигрыша / проигрыша. Так может кто-нибудь сказать мне, как они обошли этот вопрос?

Я нашел http://steveproxna01di.codeplex.com/, но искал, есть ли еще примеры, так как это скорее подход к поиску сервисов, чем подход к внедрению.

1 Ответ

0 голосов
/ 20 февраля 2012

Поскольку никто не ответил на это, я добавлю, что я фактически превратил свой экземпляр Game в оболочку и загрузчик для пользовательского экземпляра IGame, который является корневой точкой внедрения. Таким образом, я могу вводить все, что захочу.

...