Программная генерация сборок из файлов OWL с помощью ROWLEX - PullRequest
2 голосов
/ 14 мая 2009

Я использую библиотеку ROWLEX для обработки RDF-ов. Он поставляется с инструментом GUI разработки под названием OwlGrinder.exe, который может генерировать вспомогательные классы C # (точнее, сборки .NET) из моих онтологий OWL. Интересно, кто-нибудь знает, могу ли я сделать то же самое программно во время выполнения.

Ответы [ 2 ]

4 голосов
/ 25 мая 2009

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 не позволяет вам выгружать сборку. Поэтому вы не можете избавиться от сборок из ваших предыдущих запусков. Решение состоит в том, что вы каждый раз выполняете код генерации в новом домене приложений, который можно выгрузить. OwlGrinder.exe делает именно это, вы можете захотеть достичь максимума внутри MainForm.cs

2 голосов
/ 15 мая 2009

Да, мистер Лам, вы можете программно генерировать код .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 поддерживает все, что поддерживает язык. Вы можете делать лямбда-выражения и выражения linq, условия и поток управления, что угодно.

Затем вы можете скомпилировать этот класс и снова создать сборку, которую можно сохранить на диск или сохранить в памяти и динамически загружать.

...