行业资讯
📅 2026/8/18 14:37:07
DotNetIsolator实战指南:如何用Lambda在隔离沙箱中执行你的代码
DotNetIsolator实战指南如何用Lambda在隔离沙箱中执行你的代码【免费下载链接】DotNetIsolatorA library for running isolated .NET runtimes inside .NET项目地址: https://gitcode.com/gh_mirrors/do/DotNetIsolatorDotNetIsolator 是一个让你在 .NET 程序中再开一个隔离的 .NET 运行时的开源库。它基于 WebAssembly 沙箱技术让一段 .NET 代码在完全独立的内存空间里运行——没有磁盘、网络、操作系统权限宿主进程完全不受影响。本文面向 .NET 新手用最少的代码带你走通创建沙箱 → 用 Lambda 执行代码 → 拿到返回值的完整流程。什么是 DotNetIsolator为什么需要它简单说DotNetIsolator 解决的是不可信代码的隔离执行问题。传统上如果你想在 .NET 应用里执行一段第三方代码最担心的就是它乱搞你的内存、读写你的文件。而 DotNetIsolator 的做法很巧妙每个IsolatedRuntime实例就是一个 WebAssembly 沙箱由 dotnet-wasi-sdk 构建、跑在 Wasmtime 之上每个沙箱拥有完全独立的内存空间无法直接访问宿主机的磁盘、网络和操作系统宿主与沙箱之间通过MessagePack自动序列化传参和返回值调用体验和普通方法几乎一样。安装步骤一行命令引入包打开终端在你的 .NET 项目目录下执行dotnet add package DotNetIsolator --prerelease注意要加--prerelease因为目前这是实验性预发布包。安装后参考示例项目sample/ConsoleSample/的结构你的代码就已经具备接入条件了。最快上手方法用 Lambda 在沙箱里跑代码DotNetIsolator 最吸引人的 API 就是Invoke Lambda。看下面这段几乎是最小可用的完整代码using DotNetIsolator; using System.Runtime.InteropServices; using var host new IsolatedRuntimeHost().WithBinDirectoryAssemblyLoader(); using var runtime new IsolatedRuntime(host); // 宿主机环境 Console.WriteLine($宿主: {RuntimeInformation.OSArchitecture}); // 沙箱内执行 runtime.Invoke(() { Console.WriteLine($沙箱: {RuntimeInformation.OSArchitecture}); });输出结果宿主: X64 沙箱: Wasm同一个RuntimeInformation.OSArchitecture在宿主上是 X64进了沙箱就变成 Wasm——这就是隔离运行时最直观的证明。代码核心只用了三个类IsolatedRuntimeHost、IsolatedRuntime和Invoke方法对应源码见src/DotNetIsolator/IsolatedRuntimeHost.cs与src/DotNetIsolator/IsolatedRuntime.cs。带参数和返回值的 Lambda 调用方法只打印当然不过瘾我们来传递真实数据。DotNetIsolator 会自动把 Lambda 捕获的变量、参数和返回值序列化跨边界传输例如var person1 new Person(3); var person2 new Person(9); var sumOfAges runtime.Invoke(() { // 这段代码在沙箱内执行person1/person2 是捕获值会自动序列化进来 return person1.Age person2.Age; }); Console.WriteLine($沙箱计算出的年龄之和: {sumOfAges}); record Person(int Age);输出沙箱计算出的年龄之和: 12。捕获的复杂对象类、List、字典等都能通过 MessagePack 自动序列化这也是Invoke和FuncTResult重载的功劳见IsolatedRuntime.cs中的Invoke(Action)与InvokeTRes(FuncTRes)。隔离性的验证沙箱内改动不影响宿主很多新手会问我在沙箱里改个变量宿主会受影响吗答案是不会因为两者内存完全隔离。官方示例中有一个很经典的对照实验public static int StaticCounter 0; int localValue 0; runtime.Invoke(() { StaticCounter; localValue; }); Console.WriteLine($(宿主) StaticCounter{StaticCounter}, localValue{localValue});输出是(宿主) StaticCounter0, localValue0沙箱内对静态字段和局部变量的修改全部留在沙箱内这就是隔离沙箱的核心价值。进阶玩法一在沙箱里创建对象并调用方法除了 Lambda你还可以用CreateObjectT()在沙箱内直接实例化对象再通过InvokeVoid或InvokeTRes调用它的方法。示例参考sample/ConsoleSample.GuestCode/MyClass.csIsolatedObject obj runtime.CreateObjectMyClass(); string result obj.Invokestring, string(HelloWorldStr, Hi!);也可以绕过泛型直接用字符串指定程序集和类型名方便宿主不引用该程序集时的场景。进阶玩法二沙箱反向调用宿主回调Lambda 是宿主→沙箱DotNetIsolator 还支持沙箱→宿主的反向调用。宿主先注册回调runtime.RegisterCallback(getHostTime, () DateTime.Now);沙箱代码里引用DotNetIsolator.Guest包后用DotNetIsolatorHost.InvokeT调回宿主var hostTime DotNetIsolatorHost.InvokeDateTime(getHostTime);回调机制的实现见src/DotNetIsolator.Guest/DotNetIsolatorHost.cs这是构建可插拔扩展场景的关键能力。性能与资源一次初始化多个沙箱IsolatedRuntimeHost负责启动 Wasmtime 引擎约 400ms因此官方建议复用它在 DI 容器里注册为单例而每个IsolatedRuntime实例化仅需约 8ms。可以放心创建多个沙箱using var host new IsolatedRuntimeHost().WithBinDirectoryAssemblyLoader(); using var runtime1 new IsolatedRuntime(host); using var runtime2 new IsolatedRuntime(host);安全边界能隔离到什么程度DotNetIsolator 的安全模型建立在 WebAssembly 之上这是一个经过多年验证的沙箱体系。每个沙箱拥有独立内存、无磁盘网络访问宿主通过 MessagePack 序列化而非共享内存来交互安全性有保障。不过要注意项目目前是experimental状态官方明确表示未经安全审计。如果你的场景是运行完全不可信代码建议把它作为多层安全防护中的一层而不是唯一防线。总结与最佳实践清单✅ 用WithBinDirectoryAssemblyLoader()让沙箱能加载你bin目录下的程序集✅ 复用一个IsolatedRuntimeHost创建多个IsolatedRuntime✅ 简单任务用Invoke Lambda复杂对象用CreateObject 方法调用✅ 需要沙箱访问宿主资源时用RegisterCallback暴露受控接口⚠️ 牢记沙箱内修改不影响宿主这是特性不是 Bug⚠️ 生产环境使用前务必评估实验性 API 的风险现在就可以动手实践了参考sample/ConsoleSample/Program.cs写一个 20 行的 Demo感受一下在 .NET 里跑另一个 .NET的奇妙体验。无论是做插件系统、代码热执行还是学习 WebAssembly 沙箱DotNetIsolator 都是非常值得研究的一个方向。【免费下载链接】DotNetIsolatorA library for running isolated .NET runtimes inside .NET项目地址: https://gitcode.com/gh_mirrors/do/DotNetIsolator创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考