TypeLite使用T4模板遇ReflectionTypeLoadException及文件锁定问题求助
先处理第一个核心问题:ReflectionTypeLoadException的详细信息排查
你说知道要查LoaderExceptions但不知道在T4里操作,其实很简单,我们可以在T4模板里手动捕获这个异常,把具体的加载错误打印出来——毕竟这个异常的表层信息太模糊,必须看LoaderExceptions才能找到根因。
修改你的TypeLite.Net4.tt模板,把生成代码包裹在try-catch块里,比如:
<#@ template language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System" #> <#@ import namespace="System.Reflection" #> <#@ import namespace="TypeLite" #> <#@ import namespace="TypeLite.Net4" #> <# try { var ts = TypeScript.Definitions() .ForLoadedAssemblies() .ForAssembly("Shared.Web.dll") .ForAssembly("Models.dll"); ts.Write(); } catch (ReflectionTypeLoadException ex) { foreach (var loaderEx in ex.LoaderExceptions) { WriteLine("Loader Exception: " + loaderEx.Message); if (loaderEx.InnerException != null) { WriteLine("Inner Exception: " + loaderEx.InnerException.Message); } WriteLine("---"); } } #>
然后运行自定义工具,模板输出里就会显示每个加载失败的具体原因了——可能是某个依赖DLL缺失、版本不兼容,或者是Shared.Web/Models里引用了某个无法被T4宿主加载的类型(比如COM组件、未部署的NuGet包)。
接下来处理T4VSHostProcess锁定DLL导致无法复制的问题
这个问题是因为T4宿主进程(T4VSHostProcess.exe)在加载你的项目DLL后没有及时释放,导致生成项目时VS无法覆盖文件。这里有几个实用的解决办法:
紧急修复:杀死T4VSHostProcess进程
打开任务管理器,找到T4VSHostProcess.exe(就是你报错里的进程ID 9848),直接结束它。然后重新生成项目,一般就能解决复制问题。预防方案1:调整T4模板的运行时机
右键你的.tt文件 → 属性 → 把“自定义工具”暂时清空,这样VS不会自动运行模板。需要生成TypeScript定义时,再手动右键选择“运行自定义工具”;用完之后如果要生成项目,确保模板运行完毕再操作。预防方案2:修改T4模板的宿主模式
有些情况下,使用“进程外”宿主可以避免锁定DLL。在.tt文件开头添加一行:<#@ template language="C#" hostspecific="true" #>然后在模板里加载程序集时,尽量用
Host.ResolvePath()获取正确的DLL路径,避免直接加载bin目录里的文件(因为生成时bin目录会被覆盖)。检查项目引用和DLL状态
既然之前正常工作,突然失效,可能是某个依赖DLL被更新或损坏了。检查Shared.Web和Models项目的bin\Debug目录,确保所有依赖的DLL都存在,并且版本一致。比如如果Models项目引用了某个NuGet包,而Shared.Web里的版本不一样,就可能导致加载失败。
最后,排查出LoaderExceptions的具体信息后,就能针对性解决类型加载的问题——比如补充缺失的DLL、调整引用版本,或者在TypeLite配置里用.Exclude()方法跳过那些无法加载的类型。
内容的提问来源于stack exchange,提问作者Ogglas

