2

RDF-s を処理するためにROWLEXライブラリを使用しています。これには、OWL オントロジーから C# ヘルパー クラス (正確には .NET アセンブリ) を生成できる OwlGrinder.exe という設計時の GUI ツールが付属しています。実行時にプログラムで同じことができるかどうか、誰かが知っているのだろうか。

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 はまさにこれを行います。

于 2009-05-25T13:15:39.070 に答える
2

はい、ラメさん、プログラムで .NET コードを生成できます。

いくつかのオプションがあります。

  1. コードをテキストとして作成します。
    アプリ内から任意の .cs または .vb ソース ファイルをコンパイルできます。手始めに、Microsoft.CSharp.CSharpCodeProvider クラスのヘルプを参照してください。コンパイラをプログラムで呼び出し、埋め込むリソース、生成されたアセンブリを配置する場所、依存関係などを指定します。ここでのシナリオの 1 つは、template.cs ファイルを使用し、もう少しコードを埋め込んでからコンパイルすることです。結果は、そのコードから生成されたアセンブリ (必要に応じて .dll または .exe または .netmodule) です。次に、リフレクションを使用して、そのアセンブリを読み込んで呼び出すことができます。

  2. ドキュメント オブジェクト モデルを使用してコードを作成します。
    ここで関連する機能領域は「CodeDom」と呼ばれ、ドキュメント オブジェクト モデルを使用して .NET コードを作成することを除いて、Web ページの HTML DOM のように機能します。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);

などなど。通常のメソッド、コード内のあらゆる種類のステートメントなどを追加できます。私の知る限り、CodeDom のものは、言語がサポートするすべてのものをサポートしています。ラムダ式と linq 式、条件式、制御フローなど、何でも実行できます。

次に、そのクラスをコンパイルし、ディスクに保存するか、メモリに保持して動的に読み込むことができるアセンブリを再度生成できます。

于 2009-05-14T21:44:03.103 に答える