我可以将代码存储在数据库中吗? [英] Can I Store Code in a Database?

查看:323
本文介绍了我可以将代码存储在数据库中吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我想犯下将代码存储在数据库字段中的主要罪过,然后在后面的代码中对其进行评估.即

Hi All,

I want commit the cardinal sin of storing code in a database field then evaluate it in my code behind. i.e.

object.current != null && object.current.id != 0



该代码将根据当前记录而有所不同.我正在使用C#.net并想确定此语句是true/false,然后在后面的代码中相应地显示其他内容.这可能吗?只有其他开发人员才能访问代码记录.

提前谢谢.

Eric



This code will differ depending on the current record. I''m using C# .net and want to determine if this statement is true/false then have some else display accordingly in the code behind. Is this possible? Only other developers will have access to the code records.

Thanks in advance.

Eric

推荐答案

可以在运行时编译代码,这相当复杂.我认为您会觉得有帮助:链接 [
It is possible to compile code in running time, Its quite complicated. I think you would find it helpful: Link[^]

I don''t know why you would like You probably could save the code as a DLL file and then download it, and use it instead (no need to compile in run-time)


您当然可以将代码存储在数据库中,但是运行它会更加困难.要动态运行代码,您需要对其进行编译,这可以通过CodeDOM实现.它实际上可以通过常规C#编译器工作,并且此编译器始终与.NET的所有版本捆绑在一起,并由CodeDOM运行.

现在,这就是问题的样子:

您不能编译一个表达式.您可以拥有的最少代码是使用一种方法的一类.您不必将其全部存储在数据库中,但是我建议存储的代码将是一个完整的函数,否则很难对代码进行编译,验证等.您可以开发一个系统来实现一些接口,并且存储的功能将是实现.最重要的是,您可以在此实现中添加一些预先创建的代码,以便将存储的函数插入其中.但是,您可以存储整个C#文件,这更容易一些.

现在,您应该具有用于​​在内存中编译此C#文件,显示编译时错误等的代码.第二阶段将检查是否实现了所需的接口.使用Reflection,您可以执行此操作,还可以创建实现该接口的类的对象,然后调用它并返回计算结果.

现在,这会让您感到惊讶:我刚才描述的是最简单的部分!现在我们要进入一个困难的部分:

您不能在与主程序之一相同的应用程序域中执行此操作.原因如下:编译后的程序集将在此应用程序域中加载,但是 .NET出于某些非常好的原因不允许卸载任何程序集.您只能卸载整个进程或应用程序域,而不能卸载.因此,有一个解决方案:在单独的应用程序域中的内存中编译程序集.当需要编译另一个程序集时,将卸载该应用程序域并创建一个新的程序集,因为这是卸载动态编译的程序集的唯一方法.但是现在,请记住,应用程序域是完全隔离的,并且是独立的进程.这对您意味着什么?这意味着调用编译方法会遇到问题,因为您需要将参数值传递给它并返回该值.您将必须通过应用程序域之间的边界来执行此操作,因此它将需要进程间通信(IPC).为了简化此过程,类System.AppDomain中已经具有简化的IPC设施.特别是,您可以使用System.AppDomain.DoCallback.参见:
http://msdn.microsoft.com/en-us/library/system.appdomain.aspx [ ^ ],
http://msdn.microsoft.com/en-us/library/system.appdomain. docallback.aspx [ ^ ].

我在过去的解决方案中描述了相关的问题和一些体系结构框架.请参阅:
创建使用可重载插件的WPF应用程序... [ ^ ],
AppDomain拒绝加载程序集 [使用CodeDom生成代码 [创建使用可重载插件的WPF应用程序... [ ^ ](此问题最接近您的问题).

还有其他选择:

1)将程序集编译为可执行文件,具有命令行界面的控制台应用程序,并通过ExitCode或以文本形式返回值,然后将其输出到控制台.父应用程序可以使用System.Diagnostics.Process.Run运行它,并重定向控制台输出.
参见:
http://msdn.microsoft.com/en-us/library/system.diagnostics. process.aspx [^ ],
http://msdn.microsoft.com/en-us/library/system. diagnostics.process.standardoutput.aspx [ ^ ](在这里您将找到重定向示例).
对于命令行解析器,您可以使用我在CodeProject中发布的工作:基于枚举的命令行实用程序 [ ^ ]-此库非常方便且易于使用使用.

2)用一些简单的语言开发一个成熟的解析器.解析的结果应该是一个能够替换某些原始类型值并评估表达式的表达式树.我的意思是:您存储的表达式不会使用C#,而是一些简化的语言,可以解析和评估单个表达式.您可能可以为此使用一些可用的代码.

因此,现在考虑这一切,然后决定您是否真的想参与所有这一切.


—SA
You certainly can store the code in database, but running it will be way more difficult. To run code dynamically, you need to compile it, which is quite possible through CodeDOM. It actually works through regular C# compiler, and this compiler is always bundled with all versions of .NET and run by CodeDOM.

Now, this is how the problem looks like:

You cannot compile one expression. The minimal code you can have is one class with one method. You don''t have to store it all in the database, but I suggest that a stored code would be a whole function, otherwise it''s hard go make the code compile, validate it, etc. You can develop a system which implements some interface, and the stored function would be implementation. On top of that, you can add some pre-created code to this implementation, so the stored function will be inserted in it. However, you can store whole C# file, which is a bit easier.

Now, you should have code which compiles this C# file in memory, shows compile-time error, etc. Second phase would be checking up if the required interface is implemented. Using Reflection, you can do that and also create the object of a class implementing the interface and invoke it and return the result of calculation.

Now, will it be a surprise for you: what I just described was the easiest part! Now we''re getting to a difficult part:

You cannot do it in the same application domain as the one of your main program. Here is why: the compiled assembly will be loaded in this application domain, but .NET does not allow unloading of any assemblies, for some really good reasons. You can only unload a whole process or Application Domain, nothing else. So, there is one solution: compile your assembly in memory in a separate Application Domain. When you need to compile another assembly, you will unload that Application Domain and create a new one, as this is the only way to unload dynamically compiled assembly. But now, remember that the Application Domains are well isolated, as well as separate processes. What does it mean to you? It means that you will have a problem calling the compiled method, because you need to pass parameter values to it and return the value. You will have to do it through the boundary between Application Domain, so it will require Inter-Process Communications (IPC). To simplify this, the class System.AppDomain already has simplified IPC facilities in it. In particular, you can use System.AppDomain.DoCallback. See:
http://msdn.microsoft.com/en-us/library/system.appdomain.aspx[^],
http://msdn.microsoft.com/en-us/library/system.appdomain.docallback.aspx[^].

I described related problems and some architectural skeletons in my past solutions. Please see:
Create WPF Application that uses Reloadable Plugins...[^],
AppDomain refuses to load an assembly[^],
code generating using CodeDom[^],
Create WPF Application that uses Reloadable Plugins...[^] (this one is the closest to your problem).

There are some alternatives:

1) Compile assembly into an executable file, a console application with command line interface and returning value either via ExitCode or in a text form, output onto console. A parent application can run it using System.Diagnostics.Process.Run and re-direct the console output.
See:
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx[^],
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput.aspx[^] (here you will find a sample of re-direction).
For command line parser, you can you use my work published in CodeProject: Enumeration-based Command Line Utility[^] — this library is quite convenient and easy to use.

2) Develop a fully-fledged parser from some simple language. The result of parsing should be an expression tree capable of substitution of some primitive-type values and evaluation of expression. I mean it: your stored expressions will not be in C#, but is some simplistic language which would allow to parse and evaluate single expressions. You will probably able to use some available code for this.

So, now think about it all and decide is you really want to get into all this.


—SA


这篇关于我可以将代码存储在数据库中吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆