我在游戏中使用Strange IOC,而我在查看如何将视图映射到模型时遇到了麻烦。
在游戏开始时,我创建了几个敌人模型。这些模型包含操作期间使用的各种统计数据(例如损伤量,健康状况等)。我使用命令操作这些统计数据。然后,我在Start命令中遍历所有模型,并为它们创建适当的视图。每个EnemyView
都有一个EnemyMediator
,它应该触发用于管理AI的命令。
我需要一种方式告诉View
他们所属的Model
个实例。奇怪的IOC注入绑定通常通过类型或可选的附加标识符来区分。我的所有敌人模型和视图都是相同的类型,因此我必须使用此标识符。当试图实际注入实例时,就会出现问题。
我最初尝试给每个敌人模型一个GUID,然后将其传递给View
和Mediator
,但问题来自于Strange IOC注入使用静态注入标准的事实。由于显而易见的原因,尝试在Inject
属性中应用我的GUID会引发编译器错误。
这导致我使用InjectionBinder.Injector.Inject()
在Command
执行期间使用GUID手动获取绑定。这有效,但它现在增加了对我不应该需要的注入器的依赖性,而且我实际上使用注入器作为服务定位器,并且失去了注入的好处。
问题是,我不知道如何将我的EnemyView
所属的特定模型注入到我发出的命令中,因此我遇到了Service Locator风格的解决方法。
供参考,这是:
是我想要遵循的应用程序结构。
答案 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)
我设法提出了一个选项。
对于每个敌人:
然后上下文将创建敌人调解员并将敌人模型绑定到敌方调解员。
此解决方案的缺点: