C# 加载名称含点的程序集报FileNotFoundException的解决
带点号项目名引发的Assembly.Load加载异常排查与修正
核心异常原因
- 异常和项目名称中包含点号本身没有关联,本质是对
nameof表达式的编译器解析规则存在误解。很多开发者会误以为异常是点号导致Assembly.Load在加载时拆分了程序集名,实际上代码在传入Assembly.Load参数时,拿到的字符串就已经是被截断的Dots,根本不存在加载流程拆分名称的环节 - 测试代码中
Assembly.Load(nameof(TestLoadAssembly))可以正常运行,是因为编译器在当前上下文找不到名为TestLoadAssembly的命名空间或类型,会自动向上匹配到引用的程序集名称,最终返回的字符串值和预期的程序集名TestLoadAssembly完全一致 - 当写
nameof(TestWith.Dots)时,由于被引用的TestWith.Dots程序集内部存在命名空间结构TestWith,且该命名空间下定义了名为Dots的类/子命名空间,编译器会优先将表达式解析为嵌套类型的成员引用,最终返回的字符串值就是"Dots",而非预期的程序集全名TestWith.Dots。这也是异常提示找不到Dots程序集的根本原因
z行代码的修正方案
- 方案1:绕开编译器解析歧义,直接传入明确的程序集名称字符串:
var z = Assembly.Load("TestWith.Dots"); - 方案2:避免硬编码字符串,通过强引用的已知类型直接获取所属程序集。比如
TestWith.Dots程序集内存在公开类Test,可直接写:var z = typeof(TestWith.Dots.Test).Assembly;
这种写法完全不依赖字符串匹配,也不存在编译器误解析的问题 - 方案3:如果需要使用
nameof表达式拼接程序集名称,需通过完整类型路径强制解析。比如已知程序集内的类完整路径为TestWith.Dots.Test,可拼接得到正确名称:var assemblyFullName = $"{nameof(TestWith.Dots)}.{nameof(TestWith.Dots.Test)}";var z = Assembly.Load(assemblyFullName);
关联Autofac场景的注意事项
- 实际使用Autofac的
RegisterAssemblyTypes方法时,不要依赖Assembly.Load(nameof(xxx))这类带歧义的写法传入程序集参数 - 优先通过项目中已经定义的服务类型直接获取所属程序集,从根源上避免名称解析偏差导致的注册异常
- 如果需要按程序集名称扫描注册,需明确传入程序集的完整名称,不要依赖编译器对
nameof的隐式解析
内容的提问来源于stack exchange,提问作者AntimatterHedgehog
相关产品推荐
相关产品推荐

