You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Zenject为FooBarCollection注入并简化其内部FooBarItem的依赖注入?

解决Zenject中集合容器与子项依赖注入的单行配置问题

针对你遇到的问题,我们可以利用Zenject的**工厂绑定(BindFactory)**特性,结合集合类的封装,实现单行添加子项同时自动完成依赖注入,还能保证类型安全性。以下是具体实现方案:

方案一:封装集合类,内置工厂实现单行添加

1. 定义FooBarItem并声明工厂接口

首先在FooBarItem中声明工厂接口,Zenject会自动为该接口生成实现类,用于创建带依赖注入的实例:

public class FooBarItem
{
    public string Name { get; }
    // 示例依赖项
    private readonly SomeDependency _injectedDependency;

    // 构造函数注入依赖
    public FooBarItem(string itemName, SomeDependency injectedDependency)
    {
        Name = itemName;
        _injectedDependency = injectedDependency;
    }

    // Zenject自动实现的工厂接口,用于创建FooBarItem实例
    public interface Factory : IFactory<string, FooBarItem>
    {
    }
}

2. 修改FooBarCollection,注入工厂并封装添加方法

在集合类中注入FooBarItem.Factory,并提供一个AddItem方法,内部调用工厂创建实例并完成注入:

public class FooBarCollection
{
    private readonly FooBarItem.Factory _itemFactory;
    private readonly Dictionary<string, FooBarItem> _items = new();

    // 注入FooBarItem的工厂
    public FooBarCollection(FooBarItem.Factory itemFactory)
    {
        _itemFactory = itemFactory;
    }

    // 单行添加方法,自动完成依赖注入
    public void AddItem(string itemName)
    {
        var newItem = _itemFactory.Create(itemName);
        _items.Add(itemName, newItem);
    }

    // 提供获取子项的方法
    public FooBarItem GetItem(string itemName) 
        => _items.TryGetValue(itemName, out var item) ? item : null;
}

3. 在Installer中完成绑定

在你的Zenject Installer中绑定集合和工厂:

public class FooBarInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        // 绑定FooBarCollection为单例
        Container.Bind<FooBarCollection>().AsSingle();
        // 绑定FooBarItem的工厂,关联到Zenject自动生成的实现
        Container.BindFactory<string, FooBarItem, FooBarItem.Factory>().FromFactory();
    }
}

4. 使用方式

在任何需要的类中注入FooBarCollection后,只需一行代码即可添加带依赖注入的子项:

// 注入FooBarCollection
private readonly FooBarCollection _fooBarCollection;

public SomeClass(FooBarCollection fooBarCollection)
{
    _fooBarCollection = fooBarCollection;
}

// 单行添加子项
_fooBarCollection.AddItem("ItemName1");

方案二:扩展方法实现(不修改原有集合类)

如果无法修改FooBarCollection的源码,可以通过扩展方法结合工厂实现单行添加:

1. 定义扩展方法

public static class FooBarCollectionExtensions
{
    public static void AddInjectedItem(this FooBarCollection collection, FooBarItem.Factory itemFactory, string itemName)
    {
        var injectedItem = itemFactory.Create(itemName);
        // 假设FooBarCollection有公开的Add方法
        collection.Add(injectedItem);
    }
}

2. 使用方式

注入FooBarCollection和FooBarItem.Factory后,一行调用扩展方法:

private readonly FooBarCollection _fooBarCollection;
private readonly FooBarItem.Factory _itemFactory;

public SomeClass(FooBarCollection fooBarCollection, FooBarItem.Factory itemFactory)
{
    _fooBarCollection = fooBarCollection;
    _itemFactory = itemFactory;
}

// 单行添加
_fooBarCollection.AddInjectedItem(_itemFactory, "ItemName2");

方案优势

  • 单行添加:无需单独实例化子项再添加,一行代码完成创建+注入+加入集合
  • 类型安全:工厂的Create方法参数有明确类型约束,避免传参错误
  • 符合Zenject规范:完全依赖Zenject的DI机制,无需直接调用DiContainer实例化,保持代码一致性

内容的提问来源于stack exchange,提问作者JeffersonTD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:35:10