You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在React浏览器端应用中无需服务器执行动态C#代码(含逻辑/公式)

如何在React浏览器端应用中无需服务器执行动态C#代码(含逻辑/公式)

根据你的场景——手握5000+现成的C#公式,要在React浏览器环境里动态执行、完全不依赖后端、尽量少改现有代码——这件事完全可以实现,核心思路是借助.NET的WebAssembly(WASM)运行时,搭配Roslyn的浏览器端编译能力,下面给你拆解几个最实用的方案:

方案1:Blazor WASM + Roslyn WASM 动态编译执行(最贴合你的需求)

这个方案几乎能1:1复用你现在桌面端的逻辑,不用手动改写公式,直接把动态编译执行的流程搬到浏览器里。

具体怎么做:

  1. 引入.NET WASM运行时和Roslyn WASM包:不用搭建完整的Blazor应用,只需要把必要的.NET WASM runtime和Microsoft.CodeAnalysis.CSharp.Scripting.Wasm包引入到你的React项目中——现在微软已经把Roslyn编译能力打包成了可在浏览器运行的WASM模块。
  2. 移植现有公式处理逻辑:你之前解析公式片段、提取变量、生成完整C#类/方法的代码,都是C#写的对吧?直接把这部分代码放到WASM的.NET项目里就行,完全不用改逻辑,因为WASM里的.NET环境和桌面端几乎一致。
  3. React与WASM的互操作:当React的输入组件触发onChange时,把参数值(比如日期、文本框内容)传给WASM里的.NET方法,调用动态编译后的EvaluateCode方法,拿到结果后再更新React的UI状态。

举个简化的例子:
在WASM端的C#代码:

using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using System.Collections.Generic;

public static async Task<object> RunFormula(string formulaSnippet, Dictionary<string, object> paramValues)
{
    // 这里直接复用你之前生成完整类代码的逻辑
    string fullClassCode = GenerateFullClassFromSnippet(formulaSnippet, paramValues.Keys);
    
    // 配置Roslyn脚本选项,添加必要的引用和命名空间
    var scriptOpts = ScriptOptions.Default
        .AddReferences(typeof(DateTime).Assembly)
        .AddImports("System", "System.Collections.Generic");
    
    // 编译并执行代码,传入参数
    var result = await CSharpScript.EvaluateAsync(fullClassCode, scriptOpts, paramValues);
    return result;
}

在React里调用:

// 假设已经加载了.NET WASM runtime
async function handleInputUpdate(formulaId, params) {
    // 从你的存储中获取对应的C#公式片段
    const formulaSnippet = getFormulaById(formulaId);
    // 调用WASM里的方法
    const output = await window.dotnet.invokeMethodAsync('YourWasmAssembly', 'RunFormula', formulaSnippet, params);
    // 更新React状态
    setFormResult(output);
}

优缺点:

  • ✅ 优点:完全复用现有C#公式和处理逻辑,不用手动改写5000个公式;支持动态编译任意公式;纯客户端执行,无需后端。
  • ❌ 缺点:Roslyn WASM包体积不小,会增加前端打包大小;第一次加载时可能有短暂延迟;动态编译的性能比预编译稍差,但按需编译的话完全能满足输入变更的实时性需求。

方案2:提前批量编译公式为WASM模块(性能优先)

如果你的公式执行频率极高,动态编译的性能不能满足需求,可以提前把所有5000个公式编译成WASM模块,在React里按需加载调用。

具体怎么做:

  1. 写自动化编译工具:用Roslyn遍历所有公式,自动生成每个公式对应的C#类和方法,编译成.NET程序集。
  2. 编译为WASM模块:用dotnet publish命令把这些程序集编译成可在浏览器运行的WASM模块。
  3. React中加载调用:通过.NET WASM runtime加载对应的模块,调用指定的公式方法,传递参数并获取结果。

优缺点:

  • ✅ 优点:执行性能远高于动态编译,加载后执行速度快。
  • ❌ 缺点:需要提前编译所有公式,新增或修改公式都要重新编译;灵活性不如动态编译,无法支持实时修改公式的场景。

方案3:Mono WASM Runtime(轻量替代)

如果觉得Blazor+Roslyn的体积太大,可以用Mono的WASM runtime,它更轻量,支持加载预编译的.NET程序集,也能实现简单的动态编译(不过Roslyn的支持不如官方完善)。

核心思路:

把你的公式处理逻辑编译成.NET程序集,用Mono WASM runtime加载,然后通过JS与WASM的互操作调用方法,传递参数。这个方案适合对包体积敏感,但动态编译需求不高的场景。

关键注意事项:

  • 体积优化:不管用哪个方案,都要开启.NET的裁剪功能(dotnet publish -c Release时默认启用),只保留必要的程序集,减少WASM包的大小。
  • 互操作性能:JS和WASM之间的参数传递尽量简单,避免频繁传递大对象,提升交互流畅度。
  • 安全问题:动态执行C#代码存在安全风险,但你的场景是使用自己的公式,所以无需担心;如果后续要支持用户自定义公式,需要做好沙箱隔离。

总结

最适合你的是方案1,它能最大化复用你现有的代码资产,不用改写5000个公式,完全满足客户端动态执行的需求。你只需要把之前CodeDom的编译逻辑替换成Roslyn的动态编译代码,再和React做简单的互操作即可。

内容来源于stack exchange

火山引擎 最新活动