控制和内部类的反转

时间:2016-07-05 19:08:48

标签: dependency-injection inversion-of-control

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

我正在使用C#构建国际象棋程序,我已将代码分解为许多类库。我们的想法是将关于电路板位置和片段移动的所有逻辑封装在一个地方,所有关于检索和放大的逻辑都是如此。在另一个中写入游戏数据,以及关于显示棋盘和棋盘的所有数据。第三部分(UI)中的碎片。

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

第一个问题:这种方法是否正常或是否以某种方式违反了DI主体?

我一直在努力思考是否应该向IoC注册IPiece接口,甚至是IGame以外的任何接口。这是因为我希望客户端只能创建实现IGame的对象,并且所有实现其他接口的对象都会随之出现。 (我的意思是,你创造了一个新的游戏,你得到一个包含所有64个方格的棋盘,并准备好32个棋子。或者你找回一个已保存的游戏&棋盘和方块被创建并且这些棋子被放置在它在以前的位置。客户无需做任何事情。)

第二个问题:这是否正常或是否违反了依赖注入原则?

IPiece界面定义了一件作品所需的所有功能,而不考虑它是什么类型的作品。 UI甚至可以使用一个属性来构建用于显示片段的图像的资源ID,因此客户端无需知道片段的类别。

问题是有一个抽象基类实现名为IPiece的{​​{1}}接口和6个从它下降的子类(PieceBishop,{ {1}},KnightKingQueen)。我不知道如何针对Rook接口注册所有这些类,或者即使我应该这样做。

我不希望客户担心他们正在使用什么样的作品,或者创造它们。当一个新游戏开始时,这些棋子就会被创造出来。通过Pawn界面上的方法自动放置在电路板上。加载已保存的游戏,将在同一界面中通过另一种方法创建并移动到其保存位置的棋盘上,而客户端除了检索数据并将其传递给方法之外不必执行任何操作。这意味着在国际象棋引擎库中,内部类被实例化而不使用IoC。

这个想法是客户只是迭代所有的部分&将它们绘制在正确位置的屏幕板上,而无需知道对象的类别。客户端需要的所有信息都在IPiece接口定义的属性中提供。

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

1 个答案:

答案 0 :(得分:2)

  1. 理论上你应该没事。但是,考虑到IoC / DI的最大好处是它可以使测试变得更加容易,在测试时你可能需要参考实现。话虽这么说,你可以求助于InternalsVisibleToAttribute,或者你可能不需要,如果你不打算进行单元测试(虽然我强烈推荐它);
  2. 你的推理在这里听起来也不错。您可以以极简主义的方式执行此操作:首先不注册任何内容,运行代码并在需要时注册类型,而不是更早;
  3. 和以前一样,继续需要知道;或者使用@Tone的建议,如果它适合你的情况 - 有一个带有实现的IPieceFactory来保持所有的创建逻辑。