我应该使用构造函数注入还是IoC.Resolve
本文关键字:IoC Resolve 注入 构造函数 我应该 | 更新日期: 2023-09-27 18:22:22
我正在构建非常简单的棋盘游戏(只是为了学习一些新东西)。它将是跨平台的(使用Xamarin编写)。我已经编写了游戏的核心,但我不确定(仍然)应该使用构造函数注入还是IoC解析。现在我使用IoC。解析,然后传递参数。
这是我的密码。我有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。用户界面使用:
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...
}
和我的UI:
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);
}
}
我需要IGame
中的IGameBoard
。只有那里。我需要为IGame
注入棋盘和玩家。
这是我的问题:我真的需要在程序的"前端"解决IGameBoard
吗?当有人点击"开始游戏"按钮时,我在UI
中解决了这个问题。然后我通过API
传递这个板,然后传递给GameFactory
,然后传递到Game
构造函数(最后!)。在GameFactory
内部创建(或解决)IPlayerFactory
和IGameBoard
是否是一种不良做法?在这种情况下,API.CreateGame
将只有type
参数?我的意思是,对于特定的GameFactory,只有一个板(每次都一样),所以我不确定我是否需要在一开始就创建板。。。
编辑: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;
}
//...
}
我真的需要在程序的"前沿"解决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<>
。