2

我一直在使用ROWLEX库来处理 RDF-s。它附带一个名为 OwlGrinder.exe 的设计时 GUI 工具,它可以从我的 OWL 本体生成 C# 助手类(准确地说是.NET 程序集)。我想知道是否有人知道我是否可以在运行时以编程方式执行相同的操作。

4

2 回答 2

4

ROWLEX 刚刚成为开源软件,所以现在您有机会实际查看 OwlGrinder.exe 的代码并从那里复制代码。但是,这是一个简短的示例:

    private NC3A.SI.Rowlex.AssemblyGenerator generator;

    private void RunAssemblyGeneration(XmlDocument ontologyFileInRdfXml)
    {
        this.generator = new NC3A.SI.Rowlex.AssemblyGenerator();
        this.generator.GenerateAsync(ontologyFileInRdfXml, "myAssemblyName", 
                                        null, this.OnGenerationFinished);
    }

    private void OnGenerationFinished(string errorMessage)
    {
        if (errorMessage == null)
        {
            // Success
            // Displaying warnings and saving result
            string[] warnings = this.generator.Warnings;
            this.generator.SaveResult(@"C:\myAssemblyName.dll");
                // Important! One generator instance can be executed only once. 
                this.generator = null; 
                this.RejoiceOverSuccess();
            }
        else
        {
                // Failure
                this.MournOverFailure();
            }

    }

如果您想在运行时生成程序集,我假设您可能希望根据用户的要求一遍又一遍地重复该操作。您必须注意这里,因为 .NET 不允许您卸载程序集。因此,您无法摆脱以前运行的程序集。解决方案是每次在可以卸载的新 AppDomain 中执行生成代码。OwlGrinder.exe 正是这样做的,您可能希望在 MainForm.cs 中达到峰值

于 2009-05-25T13:15:39.070 回答
2

是的,Lame 先生,您可以通过编程方式生成 .NET 代码。

有几个选择。

  1. 将代码创建为文本。
    您可以从应用程序中编译任何 .cs 或 .vb 源文件。有关初学者,请参阅 Microsoft.CSharp.CSharpCodeProvider 类的帮助。您以编程方式调用编译器,指定要嵌入的资源、生成的程序集的放置位置、依赖关系等。这里的一种情况是使用 template.cs 文件,在其中嵌入更多代码,然后对其进行编译。结果是由该代码生成的程序集(.dll 或 .exe 或 .netmodule,如果您愿意)。然后,您可以使用反射加载该程序集并调用它。

  2. 使用文档对象模型创建代码。
    这里的相关功能区域称为“CodeDom”,它的工作方式类似于网页的 HTML DOM,除了文档对象模型用于创建 .NET 代码。您可以使用 DOM 元素以编程方式构建代码。

CodeDom 的例子:

var class1 = new System.CodeDom.CodeTypeDeclaration(className);
class1.IsClass=true;
class1.TypeAttributes = System.Reflection.TypeAttributes.Public;
class1.Comments.Add(new System.CodeDom.CodeCommentStatement("This class has been programmatically generated"));
// add a constructor to the class
var ctor= new System.CodeDom.CodeConstructor();
ctor.Attributes = System.CodeDom.MemberAttributes.Public;
ctor.Comments.Add(new System.CodeDom.CodeCommentStatement("the null constructor"));
class1.Members.Add(ctor);

// add one statement to the ctor:  an assignment
// in code it will look like;  _privateField = new Foo(); 
ctor.Statements.Add(new System.CodeDom.CodeAssignStatement(new System.CodeDom.CodeVariableReferenceExpression("_privateField"), new System.CodeDom.CodeObjectCreateExpression(fooType)));


// include a private field into the class
System.CodeDom.CodeMemberField field1;
field1= new System.CodeDom.CodeMemberField();
field1.Attributes = System.CodeDom.MemberAttributes.Private;
field1.Name= "_privateField";
field1.Type=new System.CodeDom.CodeTypeReference(fooType);
class1.Members.Add(field1);

等等等等。你可以在代码中添加常规方法、各种语句等等。AFAIK CodeDom 的东西支持该语言支持的一切。你可以做 lambdas 和 linq 表达式,条件和控制流,任何东西。

然后,您可以编译该类,并再次生成一个程序集,您可以将其保存到磁盘或保存在内存中并动态加载。

于 2009-05-14T21:44:03.103 回答