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

如何用ArchUnitNet的.BeAssignableTo()检查泛型类型?

解决ArchUnitNet中泛型类型的可分配性检查问题

直接使用.BeAssignableTo("MediatR.IBaseRequest")无法生效的核心原因是:这个方法匹配的是非泛型的接口类型,而你要检查的类实现的是带参数的泛型版本(如IBaseRequest<T>、IBaseRequest<T1,T2>等),两者类型不匹配。

以下是两种实用的解决方案:

方案1:针对特定参数数量的泛型接口检查

如果明确要检查的泛型接口参数数量(比如1个、2个),可以直接通过泛型类型定义来匹配:

// 获取1个参数的IBaseRequest泛型定义
var baseRequestGenericType1 = typeof(MediatR.IBaseRequest<>).GetGenericTypeDefinition();
// 获取2个参数的IBaseRequest泛型定义
var baseRequestGenericType2 = typeof(MediatR.IBaseRequest<,>).GetGenericTypeDefinition();

// 编写检查规则
ArchRuleDefinition.Classes()
    .That().ArePublic() // 根据需求调整过滤条件
    .Should().ImplementInterfaceWhere(iface => 
        iface.IsGenericType && 
        (iface.GetGenericTypeDefinition() == baseRequestGenericType1 ||
         iface.GetGenericTypeDefinition() == baseRequestGenericType2)
    )
    .Check(yourTargetAssembly);

方案2:匹配任意参数数量的IBaseRequest泛型接口

如果需要支持1到N个任意参数数量的泛型版本,可以通过检查泛型类型的全名前缀实现(.NET中泛型类型全名会以\+参数数量结尾,比如IBaseRequest<T>的全名是MediatR.IBaseRequest1`):

ArchRuleDefinition.Classes()
    .That().ArePublic()
    .Should().Satisfy(classType => 
        classType.GetInterfaces()
            .Any(iface => 
                iface.IsGenericType && 
                iface.GetGenericTypeDefinition().FullName.StartsWith("MediatR.IBaseRequest`")
            )
    )
    .Check(yourTargetAssembly);

补充简化写法

如果你的ArchUnitNet版本支持ImplementGenericInterface扩展方法,可进一步简化:

ArchRuleDefinition.Classes()
    .That().ImplementGenericInterface(typeof(MediatR.IBaseRequest<>))
    .Or().ImplementGenericInterface(typeof(MediatR.IBaseRequest<,>))
    // 按需添加更多参数数量的泛型接口
    .Should().BeSealed() // 替换为你的具体断言需求
    .Check(yourTargetAssembly);

内容的提问来源于stack exchange,提问作者Ashok Kumar Korupolu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 07:48:28