使用 Zenject 创建 RivalEntity 时出现“传递不必要的参数”错误

问题描述 投票:0回答:1

我在项目中使用 Zenject 创建 RivalEntity 时遇到“传递不必要的参数”错误,但我无法解决此问题。以下是有关问题的详细信息:

我的工厂类如下:

public class RivalFactory : PlaceholderFactory<RivalAIData, RivalEntity>
{
    public override RivalEntity Create(RivalAIData rivalAIData)
    {
        var entity = base.Create(rivalAIData);
        entity.SetAIData(rivalAIData);
        entity.Initialize();
        return entity;
    }
}

我用于设置的安装程序是:

Container.BindFactory<RivalAIData, RivalEntity, CompetitorManager.RivalFactory>().FromComponentInNewPrefab(rivalEntity);

我正在尝试使用以下代码创建一个 RivalEntity:

_rivalEntity = _rivalFactory.Create(rivalAIData);

但是,我收到“在注入‘RivalEntity’类型时传递了不必要的参数。 额外参数:RivalAIData”在这种情况下出错,我一直无法找出错误原因。我期待您的帮助。谢谢。

我尝试使用 Zenject 的工厂方法和提供的 RivalAIData 创建一个 RivalEntity。我希望创建过程能够成功,没有任何错误,并且 RivalEntity 能够使用给定的数据正确初始化。

c# unity-game-engine dependency-injection zenject
1个回答
0
投票

您没有正确使用

PlaceholderFactory
。如果你查看基类,你会发现你不应该覆盖这个方法

public class PlaceholderFactory<TParam1, TValue>
        : PlaceholderFactoryBase<TValue>, IFactory<TParam1, TValue>
    {
        // Note: Most of the time you should not override this method and should instead
        // use BindFactory<>.FromIFactory if you want to do some custom logic

除此之外,您还有 2 个选择:

  1. 对于
    MonoBehaviour
    派生类,您可以在
    [Inject]
    内使用
    RivalEntity
    属性标记一些嵌套初始化方法。对于标准类(不是从
    MonoBehaviour
    继承的),您可以使用参数定义其构造函数。 您可以在文档中的工厂页面上找到示例。
public class Enemy
{
    readonly Player _player;
    readonly float _speed;

    public Enemy(float speed, Player player)
    {
        _player = player;
        _speed = speed;
    }

    public class Factory : PlaceholderFactory<float, Enemy>
    {
    }
}

public class EnemySpawner : ITickable
{
    readonly Enemy.Factory _enemyFactory;

    public EnemySpawner(Enemy.Factory enemyFactory)
    {
        _enemyFactory = enemyFactory;
    }

    public void Tick()
    {
        if (ShouldSpawnNewEnemy())
        {
            var newSpeed = Random.Range(MIN_ENEMY_SPEED, MAX_ENEMY_SPEED);
            var enemy = _enemyFactory.Create(newSpeed);
            // ...
        }
    }
}
  1. 如果你仔细考虑并决定你只需要使用覆盖Create。那么你应该设置从
    RivalFactory
    继承的
    IFactory<RivalAIData, RivalEntity>
    。在这种情况下,您必须自己关心容器注入。举个例子:
public class CustomFactory<TParam, TObject> : IFactory<TParam, TObject>
  where TObject : MonoBehaviour
{
    private readonly DiContainer _container;
    private readonly Transform _parent;
    private readonly TObject _prefab;
    public CustomFactory(DiContainer container, Transform parentTransform, TObject prefab)
    {
        _container = container;
        _parent = parentTransform;
        this._prefab = prefab;
    }
    public virtual TObject Create(TParam option)
    {
        TObject monoObject = _container.InstantiatePrefabForComponent<TObject>(_prefab, _parent);
        /*Do something with the object*/
        return monoObject;
    }

P.S 正如我所看到的,您的代码在架构设计上存在问题。因为从构造函数调用初始化,这暗示有问题。我不能100%确定。但我强烈建议您考虑如何使用选项 1。您可以在

RivalAIData
方法中将
[Inject]
作为参数传递。并从某种控制器调用初始化。无论您选择什么,我强烈建议您从头到尾阅读factory.md页面。

© www.soinside.com 2019 - 2024. All rights reserved.