ArchUnitNET测试ASP.NET Core应用的问题咨询:规则失效、架构加载及调试
问题解答
1. 为何未检测到Handlers文件夹下未继承IRequestHandler的类?
你当前的规则仅针对实现了IRequestHandler接口的类做命名校验,那些位于Handlers文件夹但未继承该接口的类不在handlerClasses的筛选范围内,自然不会被规则检查到。要覆盖Handlers文件夹下的所有类,需调整规则的筛选逻辑:
- 利用命名空间关联文件夹(ASP.NET Core中文件夹通常对应命名空间,比如Handlers文件夹对应
xxx.Handlers):private readonly IObjectProvider<Class> handlerClasses = Classes() .That().ResideInNamespace("xxx.Handlers") // 替换为项目实际命名空间 .As("Handlers Folder Classes"); - 若想同时要求类既在Handlers文件夹又实现IRequestHandler,可叠加条件(用类型而非字符串匹配接口更可靠):
private readonly IObjectProvider<Class> handlerClasses = Classes() .That().ResideInNamespace("xxx.Handlers") .And().ImplementInterface(typeof(IRequestHandler)) .As("Valid Handler Classes"); - 注意:你规则中用
HaveNameEndingWith("handler")(小写),但通常类名结尾是Handler(大写H),若类名都是大写结尾,该规则会误判所有正确命名的类,建议改为"Handler"。
修正后的测试方法可去掉try-catch(ArchUnit会自动抛出清晰的违规信息,便于排查):
[TestMethod] public void HandlerClassShouldEndWithHandler() { Classes().That().Are(handlerClasses) .Should().HaveNameEndingWith("Handler") .Check(architecture); // 用Check()更直接,无需Assert.IsTrue }
2. ArchUnit中Architecture的作用
Architecture是ArchUnitNET对加载的程序集的结构化快照,包含了程序集中所有类型、依赖关系、继承关系、命名空间等元数据。所有架构规则的校验都基于这个快照执行:
- 即便你的应用只有一个程序集,也必须通过
ArchLoader加载并构建Architecture,否则ArchUnit无法获取代码结构信息,规则检查根本无法运行。 - 文档中加载多个程序集的示例,是为了支持跨程序集的架构规则(比如类库与Web项目之间的依赖限制),单程序集场景下加载任意类所在的程序集即可,本质都是构建当前代码库的完整结构快照。
3. 调试时IObjectProvider变量无意义名称的解决方法
IObjectProvider本质是延迟执行的查询,默认调试视图仅显示类型,不会展示你用.As("...")设置的描述,可通过以下方式优化调试体验:
- 给变量起语义化名称:比如把
ExampleLayer改成ExampleAssemblyAllTypes,ForbiddenInterfaces改成ForbiddenKeywordInterfaces,让变量名直接反映用途。 - 调试时调用Describe()方法:在调试监视窗口中输入
变量名.Describe(),就能看到通过.As()设置的自定义描述文本。 - 直接查看查询结果:调试时调用
变量名.GetObjects(architecture),可获取该查询实际匹配的所有类型集合,直观验证筛选是否符合预期。 - 内联定义简化调试:若变量复用率不高,可在规则中直接内联筛选逻辑,减少中间变量的调试复杂度。
内容的提问来源于stack exchange,提问作者GLP
相关产品推荐
相关产品推荐

