【问题标题】:Database Storage of Dynamic Methods in C#C# 中动态方法的数据库存储
【发布时间】:2011-03-28 20:20:04
【问题描述】:

如何将 C# 方法存储在 sql server 实例中以便以后动态加载和运行(在运行时)?

我即将在工作中开始一个生产测试项目,我希望在运行时加载产品的适当测试方法。

我已经简要地查看了 Reflection.Emit DynamicMethod,但它不是可序列化的。

任何建议或替代路线将不胜感激。

【问题讨论】:

  • 听起来很有趣...为什么要将 C# 方法存储在 DB 中?
  • 我们正在推出我们的第一个产品,我希望测试系统尽可能通用。拥有一个非常简单/通用的主机应用程序似乎是个好主意,它可以动态加载和运行特定于被测产品的适当测试方法。操作者只需输入产品ID号,点击go!

标签: c# sql serialization dynamic


【解决方案1】:

序列化类不会序列化任何代码,它只是序列化数据,并在反序列化时将数据重新加载到类的属性中。类上的任何方法都与您刚刚手动实例化类一样。尝试将实际代码序列化到数据库中,然后以某种方式在运行时将其编译为方法,这是一件非常古怪和奇特的事情,我正在努力理解它在测试环境中的用途。如果您真的想将源代码存储在数据库中,最好将其存储为文本,将其检索到文本文件中,然后以编程方式对其进行编译。然而,这正是 Subversion 和 Nant 等源代码控制和构建系统的用途,因此您可以说是在重新发明轮子。

关于您的最后一条评论,我认为您需要的一个很好的模式是dependency injection。您创建一个定义测试合同的接口(例如 ITester),一个简单的方法是返回一个布尔值表示通过和失败的测试方法。您照常编写测试程序,但您的测试方法采用实现 ITest 接口的类。实现 ITester 接口的类负责具体的测试实现并实际执行测试。系统的其余部分并不关心测试是什么或如何执行,它只是运行一个返回 true 或 false 的测试方法。

这样,创建一个新的测试实现所需要做的就是创建一个实现 ITester 的新类。如果您需要更改测试实现,您只需更改特定类并重新部署。如果您将每个测试器类编译成它自己的 DLL,您可以将它们作为二进制数据存储在数据库中。然后,您可以从数据库中提取它们并使用 System.Reflection.Assembly.Load 动态加载它们。请注意,这不是序列化,您将二进制程序集文件存储在数据库中。

你最终得到的是一个系统,它决定它需要运行什么测试,在数据库中查询可以运行测试代码的相关 DLL 文件,然后在运行时动态加载和执行 DLL。

【讨论】:

  • 感谢您的回答本。我知道在序列化对象时源代码不会存储在数据库中,但是在寻找执行任务的方法时,我遇到了动态方法类(我在专业软件开发方面相当新)并认为DynamicMethod(作为一个对象本身)可能以某种方式以可序列化的方式存储。
  • 我的意思不是说在序列化对象时不会将源代码存储在数据库中,而是根本不会存储任何代码。序列化只是存储数据并依赖于实际编译的类来反序列化回。话虽如此,我可以理解 DynamicMethod 的含义,因为可以说数据就是代码。即使您可以对其进行序列化,我也不确定它会有多大用处。你的描述听起来像是一件很奇怪的事情,你到底想达到什么目的。
  • 这是我的想法 - 代码是 DynamicMethod 中的数据。未来的场景是(希望)数百种不同的电子产品,它们需要针对用于构建它们的硬件组件进行大量测试。操作员将产品部件号输入到产品测试应用程序中,所有与该产品特定硬件配置相关的测试都会加载并运行。
  • 这听起来像是一个不错的实现,将程序集存储在数据库中将提供我所追求的方法的动态加载。我将不得不确定 dll 文件的大致大小并确定它作为解决方案的可扩展性,但这无疑给了我一个很好的起点。谢谢(如果我有足够的代表,我会 +1)
  • 将接口 (ITester) 编译成您无需重新编译的单独 dll,以确保在发布主应用程序的未来版本时不会破坏现有插件。
【解决方案2】:

出于兴趣,如果您将表达式 树用于您的方法,则有一个项目可以序列化这些树 - 请参阅 SO 帖子 here

【讨论】:

    猜你喜欢
    • 2015-08-02
    • 2012-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多