c# 将字符串作为代码执行...值得付出努力吗?

Posted

技术标签:

【中文标题】c# 将字符串作为代码执行...值得付出努力吗?【英文标题】:c# executing a string as code...is it worth the effort? 【发布时间】:2011-03-29 21:39:30 【问题描述】:

到目前为止的故事如下:

我正在做一个 C# winforms 应用程序,以方便指定设备以进行租用报价。

在其中,我有一个 List<T> 约 1500 件库存商品。

这些项目有一个名为AutospecQty 的属性,它有一个get 访问器,需要执行一些特定于每个项目的代码。此代码将引用列表中的其他各种项目。

因此,例如,一个项目(我们称之为Item0001)有这个get 访问器,它可能需要执行一些可能看起来像这样的代码:

[some code to get the following items from the list here]

if(Item0002.Value + Item0003.Value > Item0004.Value)
 return Item0002.Value 
else
 return Item0004.Value 

这一切都很好,但是这些代码可能每周都会发生变化,所以我尽量避免经常重新部署。此外,每个项目可能(将)具有完全不同的代码。有些会查询列表,有些会做一些很长的数学函数,有些会像上面一样简单添加......有些将取决于列表中不包含的变量。

我想做的是将每个项目的代码存储在我的数据库中的一个表中,然后当应用程序启动时,只需将相关代码拉出并将其放入一个列表中,准备在时间执行时执行来了。

我在互联网上看到的大多数关于将字符串作为代码执行的示例看起来都非常冗长、令人费解和/或对新手编码器不是特别友好(我是一个完全的业余爱好者),而且不要似乎考虑到被传递的变量。

所以问题是:

    有没有更简单/更简单的方法来实现我想要做的事情? 如果 1=false(我猜是这种情况),是否值得为这种方法的所有潜在问题付出努力,或者我是否可以更好地花时间在应用程序中编写自动更新功能并保留它全部在主应用中(因此用户只需让应用每周更新一次)? 我的另一个(可能是坏的)想法是将所有 autospec 代码转移到一个单独的 DLL 中,或者只是在必要时重新部署它,或者甚至可以在共享网络驱动器上引用单个 DLL?

我想无论我走哪条路,这都是一个相当危险的领域。谁能告诉我,如果我打开一罐虫子,最好把它关好并真正关起来?

有没有更好的方法来处理整个事情?我有一个习惯,就是把我想要解决的事情复杂化:P

就像附加信息一样,autospec 代码不会是用户输入的。我每周都会更新它(没有其他人可以访问它),所以希望这至少可以缓解一些安全问题。

抱歉,如果我解释得不好。

提前致谢

【问题讨论】:

您是否考虑过使用 IronPython 等脚本语言进行计算? 【参考方案1】:

需要考虑的一些选项:

1) 如果您有一个具有自动构建和部署功能的良好持续集成系统,那么每周部署会是个问题吗?

2) 您是否考虑过 MEF 或类似的方法,它允许您仅替换包含新规则的单个 DLL?

3) 如果公式可以简单地表达(无需评估某些代码,例如 A+B+C+D > E+F+G+H => J 或 K),您也许可以使用反射来收集参数值,然后应用它们。

4) 您可以使用 .NET 4 中的表达式并从数据库构建表达式树,然后对其进行评估。

【讨论】:

在对此进行更多研究后,开始每周只有一次,如果一切按计划进行,几个月后事情就会放缓(哈哈!是啊,对... ),所以我想我只是要为自己构建一个不错的更新功能。这里提到的大多数事情听起来可能超出了我的能力范围,或者肯定不值得花时间投资。无论如何,谢谢,伙计们。【参考方案2】:

看来您可以通过实施specification pattern 得到很好的服务。

正如***所描述的那样:

通过使用布尔逻辑将业务逻辑链接在一起,可以重新组合业务逻辑。

【讨论】:

【参考方案3】:

您是否考虑过类似 MEF 之类的东西,那么您可能有很多小 dll 来实现您的计算的各种版本,并简单地引用从数据库中加载的那个。

这是假设您可以将它们全部包装在一个(或少量)接口中。

【讨论】:

【参考方案4】:

我将通过创建程序可以解释以执行规则的域特定语言来解决这个问题。然后将 DSL 代码的片段放入数据库中。

如你所见,我也喜欢把事情复杂化。 :-) 但只要简化长期使用,它就可以工作。

【讨论】:

我还不知道有什么方法可以创建不难以置信复杂的 DSL。 @Kragen - 编写一个可以使用递归解析器计算“A = 5; B = 10; C = 3; X = A * (B + C)”的程序是一个大二项目。通过创建自定义表达式树(包括条件“if ... else ...”逻辑)来提高性能有点额外。用内置表达式替换变量(“PREVIOUS_ITEM_COST”)很简单。我真的不认为这会那么难。 DSL 与构建通用语言不同。它通常甚至不是图灵完备的。 我已经为各种项目完成了其中的几个,难度不大。我编写的一种语言仅用于为我开发的另一个子系统生成测试。另一个是向大型机平面文件格式文件解释器添加消歧信息。这些有趣的项目让花在另一个无意识中间件组件上的所有时间都值得。【参考方案5】:

您可以让您的程序在运行时将您的规则编译成一个类,该类使用CSharpCodeProvider 充当插件。

有关如何执行此操作的示例,请参阅 Compiling code during runtime。

【讨论】:

请注意,在运行时编译代码会锁定程序集使用的内存,因为您无法卸载正在运行的程序集。我在 ASP.NET 中使用这种技术关闭了内存不足异常的 IIS 服务器。 @neontapir - 您可以将编译后的代码加载到单独的应用程序域中。 没错,单独的应用程序域可以回避这个问题。在我们的案例中,我们最终改为编写 IronRuby 脚本引擎解决方案。

以上是关于c# 将字符串作为代码执行...值得付出努力吗?的主要内容,如果未能解决你的问题,请参考以下文章

Linux 上的 WCF - 值得付出努力吗

液体布局仍然相关吗?

突变测试在实践中有用吗?

使用 C# 创建 COM 扩展 - 值得吗?

你都付出了哪些努力

你都付出了哪些努力