Dependency injection 控制反转与内部类

Dependency injection 控制反转与内部类,dependency-injection,inversion-of-control,Dependency Injection,Inversion Of Control,我有三个关于控制反转的问题 我正在使用C#构建一个国际象棋程序,并且我已经将代码分解为许多类库。其思想是封装关于棋盘位置和棋子在一个位置移动的所有逻辑,关于在另一个位置检索和写入游戏数据的所有逻辑,以及关于在第三个位置(UI)显示棋盘和棋子的所有数据 我有一个库,它是应用程序的“业务层”,包含代表游戏、玩家、棋盘、棋盘上的方块和棋子的接口和类。每个对象都有一个公共接口。然而,实现这些接口的类是内部的。在我看来,这种方法将防止库外的代码实例化,甚至不知道任何内部代码,这是正确的方法。客户端应该只使

我有三个关于控制反转的问题

我正在使用C#构建一个国际象棋程序,并且我已经将代码分解为许多类库。其思想是封装关于棋盘位置和棋子在一个位置移动的所有逻辑,关于在另一个位置检索和写入游戏数据的所有逻辑,以及关于在第三个位置(UI)显示棋盘和棋子的所有数据

我有一个库,它是应用程序的“业务层”,包含代表游戏、玩家、棋盘、棋盘上的方块和棋子的接口和类。每个对象都有一个公共接口。然而,实现这些接口的类是内部的。在我看来,这种方法将防止库外的代码实例化,甚至不知道任何内部代码,这是正确的方法。客户端应该只使用接口的方法和属性

第一个问题:这种方法是正确的还是违反了DI原则

我一直在苦苦思索是否应该向国际奥委会注册
IPiece
接口,甚至是
IGame
以外的任何接口。这是因为我希望客户机只能够创建实现
IGame
的对象,所有实现其他接口的对象都会随之产生。(我的意思是,你创建了一个新游戏,你得到了一个包含所有64个方格和32个棋子的棋盘。或者你检索了一个保存的游戏&棋盘&方格被创建了&棋子被放在了先前的位置上。客户无需做任何事情)

第二个问题:这可以吗,还是违反了依赖注入原则

IPiece
接口定义了工件所需的所有功能,而不考虑工件的类型。UI甚至可以使用一个属性来构建用于显示工件的图像的资源ID,因此客户端不需要知道工件的类是什么

问题是有一个抽象基类实现了名为
Piece
ipiee
接口,以及从它派生的6个子类(
Bishop
Knight
King
Queen
Rook
Pawn
)。我不知道如何根据
IPiece
接口注册所有这些类,甚至不知道是否应该注册

我不想让客户不得不担心他们在使用什么样的产品,或是制作什么样的产品。当一个新游戏开始时,通过
IGame
界面上的方法自动创建并放置棋子。加载已保存的游戏时,将通过同一界面中的另一种方法创建棋子并将其移动到棋盘上的已保存位置,客户端无需执行任何操作,只需检索数据并将其传递给该方法。这意味着在国际象棋引擎库中,内部类是在不使用IoC的情况下实例化的

其思想是,客户机只需迭代所有片段并将它们绘制在屏幕上正确的位置,而不需要知道对象的类。客户需要的所有信息都在
IPiece
界面定义的属性中提供

第三个问题:这可以吗?或者我应该定义
IBishop
,等等&将类注册到接口IoC,即使IoC映射永远不会在类库之外使用

  • 理论上你应该没事。然而,考虑到IoC/DI最大的好处是它可以使测试变得更容易,您可能需要在测试它时参考实现。也就是说,如果不打算进行单元测试,您可以求助于,也可以不求助于(尽管我强烈推荐)
  • 你的推理在这里听起来也不错。你可以用一种最简单的方式做到这一点:不注册任何东西,运行代码,按照需要注册类型,而不是更早
  • 和以前一样,在需要了解的基础上进行;或者,如果@Tone的建议适合您的情况,也可以使用@Tone的建议—使用一个带有实现的IPieceFactory来保持所有创建逻辑处于打开状态

  • 我认为你需要调查一下工厂,然后你可以把每件产品的参考资料保存在它们所属的地方。我发布了一篇文章,其中包含了一些关于如何使用工厂实现的示例,这些示例可能会给您一个想法。这个问题还与该主题的其他相关信息相关联。这是有道理的。我确实需要为每个类中的每个方法构建单元测试。我没有考虑内部构件对测试的影响。我会考虑一下。