映射相同类型的模型以查看实例

时间:2014-05-26 10:56:14

标签: c# dependency-injection unity3d inversion-of-control

我在游戏中使用Strange IOC,而我在查看如何将视图映射到模型时遇到了麻烦。

在游戏开始时,我创建了几个敌人模型。这些模型包含操作期间使用的各种统计数据(例如损伤量,健康状况等)。我使用命令操作这些统计数据。然后,我在Start命令中遍历所有模型,并为它们创建适当的视图。每个EnemyView都有一个EnemyMediator,它应该触发用于管理AI的命令。

我需要一种方式告诉View他们所属的Model个实例。奇怪的IOC注入绑定通常通过类型或可选的附加标识符来区分。我的所有敌人模型和视图都是相同的类型,因此我必须使用此标识符。当试图实际注入实例时,就会出现问题。

我最初尝试给每个敌人模型一个GUID,然后将其传递给ViewMediator,但问题来自于Strange IOC注入使用静态注入标准的事实。由于显而易见的原因,尝试在Inject属性中应用我的GUID会引发编译器错误。

这导致我使用InjectionBinder.Injector.Inject()Command执行期间使用GUID手动获取绑定。这有效,但它现在增加了对我不应该需要的注入器的依赖性,而且我实际上使用注入器作为服务定位器,并且失去了注入的好处。

问题是,我不知道如何将我的EnemyView所属的特定模型注入到我发出的命令中,因此我遇到了Service Locator风格的解决方法。

供参考,这是:

是我想要遵循的应用程序结构。

4 个答案:

答案 0 :(得分:1)

这不是一个直接的解决方案,但这就是我解决这个问题的方法。我为所有敌人创建了一个单身人士模型。该模型包含一个字典,其中键是view.GetInstanceID(),该值是一个保存该特定敌人的统计数据的类。

public class EnemyModel : IEnemyModel
{
    // int is the id of the enemy's instance id in the view i.e. view.GetInstanceID()
    public IDictionary<int,Enemy> enemyDict {get;set;}

    public EnemyModel ()
    {
        enemyDict = new Dictionary<int,Enemy>();
    }
}

public class Enemy
{
    public bool  isDangerous = false;
    public float health = 1;
}

答案 1 :(得分:1)

我有同样的问题要解决,这是我提出的解决方案。

EnemyMediator对敌人有反对意见(但不注射,甚至可能是私人的)。 EnemyMediator需要有一些单身人士游戏模型作为财产当前的敌人;

现在,当您在某些命令中创建敌人时,实例化敌人(注入游戏模型),首先创建模型并将其添加到游戏模型的currentEnemy值。现在你实例化视图。

在PostConstruct方法中,您可以阅读currentEnemy值表单游戏模型并将其设置在Mediator中。

当您发射信号/事件时,您将敌人添加为参数。现在命令包含有关模型的信息。

我不喜欢将模型添加到调解员中,但我还没有找到更好的解决方案。

答案 2 :(得分:1)

我在尝试理解IOC内部更合适的时候遇到了同样的疑惑和疑问。 所以,阅读文档我读到的东西就像“模型就像Value Objects(VO)”。 所以我提出了这个使用Unity潜力的解决方案。 这是我的设计示例:

  • 我创建了一个Mononehaviour的“EnemyModel”类并实现了一个通用的IEnemyModel接口

  • 在场景加载期间,在上下文的StartCommand中,我使用AddComponent将EnemyModel添加到每个EnemyView。每个EnemyModel的数据都是从描述场景数据属性的文件或数据库加载的。

  • 介体有对EnemyView和EnemyModel的引用(通过界面)

  • 在调解器中调度命令时(我使用信号),EnemyModel作为参数传递。

  • 在命令中我引用了作为参数传递的数据,因此命令已经知道要使用的数据,并且它实际上正在处理模型。

我认为这比传递某种ID并尝试通过数据管理器解析数据更好。此外,如果EnemyModel是一个附加到EnemyView游戏对象的monobehaviour,则更容易从编辑器调试他的值。

您怎么看?

答案 3 :(得分:0)

我设法提出了一个选项。

对于每个敌人:

  • 创建敌人模型。
  • 为每个敌人创建一个单独的上下文,并将模型存储在其中 那里。
  • 在EnemyView类型和。之间创建一个中介绑定 EnemyMediator在敌人背景下输入。
  • 在上下文中创建敌人视图。

然后上下文将创建敌人调解员并将敌人模型绑定到敌方调解员。

此解决方案的缺点:

  1. 它导致一个很多的上下文,带来了他们自己的 注射粘合剂等。
  2. 导致大量使用跨上下文 绑定,可能会污染绑定空间。这可能是 通过修改Context来修复使用分层查找(我 在查看跨语境之前,可能会尝试在今天晚些时候做 粘合剂。