在LINQPad中于独立AppDomain执行类的可行性问询
在LINQPad中跨独立AppDomain运行自定义类的实现方案
当然可以实现!你遇到的FileLoadException主要是因为LINQPad生成的临时程序集有特殊的加载机制,加上你的代码缺少跨AppDomain访问的关键配置。下面是具体的问题分析和修正方案:
问题根源
- 跨域对象的类型要求:你定义的
AdHocQuery没有继承MarshalByRefObject,而CreateInstanceAndUnwrap要求跨AppDomain访问的对象必须继承这个类——因为AppDomain之间是完全隔离的,只有继承该类的对象才能通过代理在域间传递引用。 - 程序集路径获取错误:LINQPad的临时查询程序集不是常规的磁盘加载方式,直接用
typeof(AdHocQuery).Assembly.Location可能拿到无效的路径,导致新AppDomain无法找到该程序集。 - AppDomain配置缺失:新创建的AppDomain默认的程序集搜索路径可能不包含LINQPad的临时程序集目录,进而引发加载失败。
修正后的完整代码
void Main() { // 配置新AppDomain的搜索路径,确保能找到LINQPad的临时程序集 var domainSetup = new AppDomainSetup { ApplicationBase = AppDomain.CurrentDomain.BaseDirectory, // 将LINQPad临时程序集目录加入私有搜索路径 PrivateBinPath = Path.GetDirectoryName(Util.CurrentQueryAssembly.Location) }; AppDomain customDomain = AppDomain.CreateDomain("MyDomain", null, domainSetup); try { // 使用LINQPad提供的Util工具类获取当前查询的程序集信息,更可靠 var queryInstance = (AdHocQuery)customDomain.CreateInstanceAndUnwrap( Util.CurrentQueryAssembly.FullName, typeof(AdHocQuery).FullName); queryInstance.Run(); } finally { // 确保AppDomain被卸载,释放资源 AppDomain.Unload(customDomain); } } // 必须继承MarshalByRefObject,才能在AppDomain间通过代理访问 class AdHocQuery : MarshalByRefObject { public void Run() { // 验证是否在目标AppDomain中运行 Console.WriteLine($"当前运行的AppDomain名称:{AppDomain.CurrentDomain.FriendlyName}"); // 这里可以添加你的业务逻辑 } }
关键说明
MarshalByRefObject的必要性:这个类是.NET中实现跨AppDomain对象访问的核心,它允许CLR创建对象的代理,让调用方在自己的AppDomain中通过代理操作另一个域中的对象。Util.CurrentQueryAssembly:LINQPad提供的工具属性,能准确获取当前查询生成的临时程序集信息,比直接使用typeof(...).Assembly更稳定,能避开LINQPad特殊的程序集加载逻辑带来的问题。AppDomainSetup配置:通过设置PrivateBinPath,让新AppDomain知道去哪里找LINQPad生成的临时程序集,避免加载失败。
额外注意事项
如果你的AdHocQuery依赖了其他第三方程序集,需要确保这些程序集在新AppDomain的搜索路径中,或者可以通过订阅新AppDomain的AssemblyResolve事件来手动加载缺失的程序集。
内容的提问来源于stack exchange,提问作者Terry
相关产品推荐
相关产品推荐

