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

Unity 4.0.1:如何检索容器已实例化的所有对象?

在Unity 4.0.1中检索容器实例化的对象

嘿,刚好我之前也研究过这个问题——Unity 4.0.1本身并没有提供像你想要的GetAllInstantiatedObjects()这样的内置API来直接获取容器已经创建的所有实例。不过我们可以通过扩展Unity的容器功能来实现这个需求,下面给你两种可行的方案:

方案一:自定义容器扩展,跟踪所有实例

这个方法会创建一个容器扩展,在每个对象被容器实例化完成后自动记录下来,支持按类型筛选。

首先创建跟踪扩展类:

using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.ObjectBuilder;

public class InstanceTrackingExtension : ContainerExtension
{
    private readonly List<object> _trackedInstances = new List<object>();

    // 获取所有被跟踪的实例
    public IEnumerable<object> AllInstantiatedObjects => _trackedInstances.AsReadOnly();

    // 获取指定类型的实例
    public IEnumerable<T> GetAllInstantiatedObjects<T>()
    {
        return _trackedInstances.OfType<T>();
    }

    protected override void Initialize()
    {
        // 添加一个构建策略,在对象初始化完成后记录实例
        Context.Strategies.Add(new InstanceTrackingStrategy(_trackedInstances), UnityBuildStage.PostInitialization);
    }

    private class InstanceTrackingStrategy : BuilderStrategy
    {
        private readonly List<object> _instanceList;

        public InstanceTrackingStrategy(List<object> instanceList)
        {
            _instanceList = instanceList;
        }

        public override void PostBuildUp(IBuilderContext context)
        {
            var createdInstance = context.Existing;
            if (createdInstance != null && !_instanceList.Contains(createdInstance))
            {
                _instanceList.Add(createdInstance);
            }
        }
    }
}

使用方式

把这个扩展添加到你的容器中,之后所有通过容器Resolve或依赖注入创建的对象都会被自动跟踪:

var unityContainer = new UnityContainer();
var trackingExtension = new InstanceTrackingExtension();
unityContainer.AddExtension(trackingExtension);

// 注册并创建实例
unityContainer.RegisterType<IFoo, Foo>();
var foo1 = unityContainer.Resolve<IFoo>();
var foo2 = unityContainer.Resolve<IFoo>();
var bar = unityContainer.Resolve<Bar>();

// 获取所有实例
IEnumerable<object> allInstances = trackingExtension.AllInstantiatedObjects;
// 获取所有IFoo类型的实例
IEnumerable<IFoo> instantiatedFoos = trackingExtension.GetAllInstantiatedObjects<IFoo>();

⚠️ 注意事项:

  • 这个方案会持有所有实例的引用,瞬态对象会因为被跟踪列表引用而无法被GC回收,如果你需要管理内存,记得在对象不再使用时手动从_trackedInstances中移除,或者只跟踪特定生命周期的对象(比如单例)。
  • 仅跟踪通过当前容器创建的对象,手动new的对象不会被记录;如果使用子容器,需要给子容器单独添加这个扩展。

方案二:仅检索单例实例

如果你只关心单例对象,Unity提供了Registrations属性可以获取所有注册信息,我们可以从中筛选出单例注册并获取实例:

using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.Unity;

public static class UnityContainerExtensions
{
    public static IEnumerable<T> GetAllSingletonInstances<T>(this IUnityContainer container)
    {
        return container.Registrations
            // 筛选出单例生命周期的注册
            .Where(reg => reg.LifetimeManager is SingletonLifetimeManager)
            // 解析获取实例
            .Select(reg => container.Resolve(reg.RegisteredType))
            // 转换为指定类型
            .OfType<T>();
    }
}

使用时直接调用扩展方法即可:

IEnumerable<IFoo> singletonFoos = unityContainer.GetAllSingletonInstances<IFoo>();

这个方法不会持有额外引用,不会影响GC,但只能获取单例对象,瞬态对象无法通过这种方式检索。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:25:17