使用 ROWLEX 以编程方式从 OWL 文件生成程序集

发布于 2024-07-20 08:47:07 字数 215 浏览 13 评论 0原文

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

I have been using the ROWLEX library to handle RDF-s. It is shipped with a designtime GUI tool called OwlGrinder.exe that can generate C# helper classes (.NET assemblies to be exact) from my OWL ontologies. I wonder if anyone knows if I could do the same programatically in runtime.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一杆小烟枪 2024-07-27 08:47:07

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 中达到峰值

ROWLEX just became open source, so now you have the chance to actually look inside the code of OwlGrinder.exe and copy the code from there. However, here is a short example:

    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();
            }

    }

If you want to generate assemblies in runtime, I assume that you might want to repeat that over and over again as your user demands. You have to watch out here, because .NET does not allow you to unload an assembly. Therefore you cannot get rid of the assemblies from your previous runs. The solution is that you execute the generation code every time in a new AppDomain which can be unloaded. OwlGrinder.exe does exactly this, you might want to peak inside the MainForm.cs

断舍离 2024-07-27 08:47:07

是的,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 的东西支持该语言支持的一切。 您可以执行 lambda 和 linq 表达式、条件和控制流等任何操作。

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

Yes, Mr Lame, you can programmatically generate .NET code.

There are a couple options.

  1. Create the code as text.
    You can compile any .cs or .vb source file from within an app. See the help for the Microsoft.CSharp.CSharpCodeProvider class, for a starter. You invoke the compiler programmatically, specifying the resources to embed, where to put the generated assembly, the dependencies, and so on. One scenario here is using a template.cs file, embedding a little more code into it, and then compiling it. The result is an assembly (.dll or .exe or .netmodule if you like) resulting from that code. You can then load that assembly and call into it, using reflection.

  2. Create the code using a document object model.
    The relevant feature area here is called "CodeDom" and it works like the HTML DOM for web pages, except the document object model is used to create .NET code. Programmatically you construct the code, using DOM elements.

example of the CodeDom thing:

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);

etc etc. You can add regular methods, all sorts of statements in the code, and so on. AFAIK the CodeDom stuff supports everything the language supports. You can do lambdas and linq expressions, conditionals and control flow, anything.

You can then compile that class, and again produce an assembly that you can save to disk or keep in memory and load dynamically.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文