我应该使用Constructor Injection还是IoC.Resolve?

时间:2015-11-18 17:20:11

标签: c# .net dependency-injection inversion-of-control ioc-container

我正在构建非常简单的棋盘游戏(只是为了学习一些新东西)。它将是跨平台的(使用Xamarin编写)。我已经编写了游戏的核心,但我不确定(仍然)是否应该使用构造函数注入 IoC resolve 。现在我使用 IoC.Resolve ,然后通过参数。

这是我的代码。我有Game有2个依赖项和类型。我有工厂来创建游戏和玩家:

Abc.MyGame.Domain

  • 接口

    public interface IGame
    {
        GameType GameType { get; }
        IGameBoard GameBoard { get; }
        List<IPlayer> Players { get; }
    
        // Other stuff...
    }
    
    public interface IGameBoard
    {
        //board stuff...
    }
    
    public interface IPlayer
    {
        int PlayerId { get; set; }
        PlayerType PlayerType { get; set; }
    }
    
  • 工厂界面

    public interface IGameFactory
    {
        IGame CreateGame(GameType type, IGameBoard board);
    }
    
    public interface IPlayerFactory
    {
        IPlayer CreatePlayer(PlayerType type, int id);
    }  
    
  • 工厂

    public class GameFactory : IGameFactory
    {
        public IGame CreateGame(GameType type, IGameBoard board)
        {
            switch (type)
            {
                case GameType.SinglePlayer:
                    return new MyGame(type, board,
                        new List<IPlayer> { CreateHuman(1), CreateBot(2) });
                case GameType.TwoPlayers:
                    return new MyGame(type, board,
                        new List<IPlayer> { CreateHuman(1), CreateHuman(2) });
                case GameType.Online:
                    return new MyGame(type, board,
                        new List<IPlayer> { CreateHuman(1), CreateOnlinePlayer(2) });
    
            }
            return null;
        }
    }
    

然后,有一个API。由UI使用:

Abc.MyGame.API

public class GameAPI
{
    public IGame CurrentGame { get; set; }

    public IGame CreateGame(IGameFactory gameFactory, GameType type, IBoard board)
    {
        CurrentGame = gameFactory.CreateGame(type, board);
        return CurrentGame;
    }

    // Other stuff, like make move etc...
}

...和我的用户界面:

Abc.MyGame.UI.WinForms

public partial class Form1 : Form
{
    private GameAPI api = new GameAPI();
    IKernel kernel = new StandardKernel();

    public Form1()
    {
        InitializeComponent();

        // Load all dependencies
        var modules = new List<INinjectModule> { new GameModule() };
        kernel.Load(modules);
    }

    private void buttonStartGame(object sender, EventArgs e)
    {
        IGameBoard board = kernel.Get<IGameBoard>(
            new ConstructorArgument("width", 7), 
            new ConstructorArgument("height", 6)
        );

        api.CreateGame(kernel.Get<IGameFactory>(), GameType.TwoPlayers, board);
    }
}

我需要在IGameBoardIGame。只有在那里。我需要将棋盘和玩家注入IGame

这是我的问题/问题: 我是否真的需要在我的计划的“前端”解决IGameBoard?当我点击“开始游戏”按钮时,我会在UI中解决它。然后我通过API传递此板,然后将其传递给GameFactory,然后将其传递给Game构造函数(最后!)。在IPlayerFactory内创建(或解决)IGameBoardGameFactory是不好的做法?在这种情况下,API.CreateGame只有type个参数?我的意思是对于特定的GameFactory,只有一块板(evey时间相同),所以我不确定我是否需要在一开始就创建板...

编辑: MyGame构造函数:

public class MyGame : IGame
{
    public IBoard Board { get; }
    public GameType Type { get; }
    public List<IPlayer> Players { get; }

    public MyGame(GameType type, IBoard board, List<IPlayer> players)
    {
        Type = type;
        Board = board;
        Players = players;
    }

    //...
}

1 个答案:

答案 0 :(得分:0)

  

我真的需要在我的程序的“前端”解决IGameBoard吗?

是的,需要在应用程序的入口点和生命周期范围(如果有)的开始处解决依赖关系。通常,这是抽象的(就像在ASP.NET MVC中一样),因此您不必自己调用kernel.Get<>(或任何其他container.Resolve<>)。在WinForms中没有这样的机制,所以你必须自己解决依赖关系,最好只有这样的根依赖:

public static class Program
{
    private static void Main()
    {
        var kernel = new StandardKernel();
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(kernel.Get<Form1>());
    }
}

通过在主表单上添加正确的依赖项(可能包括游戏中的工厂),您的应用程序中不再需要kernel.Get<>

相关问题