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

DryIoC如何实现IsResolved检测当前作用域服务是否已实例化

如何在DryIoC当前作用域内检查指定服务是否已被创建

DryIoC原生确实没有直接提供IsResolved方法,但可以通过它公开的作用域缓存访问API实现完全等价的判断逻辑,整个过程不会触发服务实例化,完全符合预期需求。

注意:该判断逻辑仅对单例(Reuse.Singleton)、作用域单例(Reuse.Scoped)生命周期的服务生效。瞬态(Reuse.Transient)服务每次解析都会生成新实例,不会存入作用域缓存,本身不存在“已创建可复用”的语义,因此判断对瞬态服务始终返回false,符合容器生命周期设计。

实现代码

首先定义静态扩展方法,直接复用DryIoC公开的作用域缓存读取能力,不需要反射,性能和原生API一致:

using DryIoc;

public static class DryIocExtensions
{
    public static bool IsResolved<TService>(this IResolverContext resolver)
    {
        return resolver.IsResolved(typeof(TService));
    }

    public static bool IsResolved(this IResolverContext resolver, Type serviceType, object serviceKey = null)
    {
        // 先检查服务是否完成注册,未注册直接返回false
        var registrations = resolver.GetServiceRegistrations()
            .Where(r => r.ServiceType == serviceType && Equals(r.ServiceKey, serviceKey))
            .ToList();
        if (registrations.Count == 0) return false;

        // 获取当前上下文对应的作用域,根容器对应根作用域
        var currentScope = resolver.CurrentScope ?? resolver.RootScope;
        if (currentScope == null) return false;

        // 遍历注册项,直接从作用域缓存读取已存在实例,不触发创建逻辑
        foreach (var reg in registrations)
        {
            if (currentScope.TryGet(reg.Factory.InstanceCacheKey, out _))
            {
                return true;
            }
        }
        return false;
    }
}

使用示例

用法和预期写法完全一致:

var container = new Container();
container.Register<S>(Reuse.Scoped); // 也支持Reuse.Singleton生命周期

// 服务解析前判断,返回false
if (container.IsResolved<S>())
{
    // 解析前不会进入该分支
}

var s = container.Resolve<S>();

// 服务解析后判断,返回true
if (container.IsResolved<S>())
{
    // 解析后会进入该分支
}

嵌套作用域场景下,判断会自动限定在当前作用域范围内,不会跨作用域误判:

var container = new Container();
container.Register<S>(Reuse.Scoped);
using (var outerScope = container.OpenScope())
{
    var outerS = outerScope.Resolve<S>();
    Console.WriteLine(outerScope.IsResolved<S>()); // 输出:True

    using (var innerScope = outerScope.OpenScope())
    {
        Console.WriteLine(innerScope.IsResolved<S>()); // 输出:False,内层作用域尚未解析S
        var innerS = innerScope.Resolve<S>();
        Console.WriteLine(innerScope.IsResolved<S>()); // 输出:True
    }
}

带服务Key的注册场景,调用IsResolved时传入对应serviceKey参数即可完成判断。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:42:16