Программная генерация сборок из файлов OWL с помощью ROWLEX
Я использую библиотеку ROWLEX для обработки RDF-ов. Он поставляется с инструментом GUI разработки под названием OwlGrinder.exe, который может генерировать вспомогательные классы C# (точнее, сборки.NET) из моих онтологий OWL. Интересно, кто-нибудь знает, могу ли я сделать то же самое программно во время выполнения.
2 ответа
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
Да, мистер Лам, вы можете программно генерировать код.NET.
Есть пара вариантов.
Создайте код в виде текста.
Вы можете скомпилировать любой исходный файл.cs или.vb из приложения. См. Справку по классу Microsoft.CSharp.CSharpCodeProvider, для начала. Вы вызываете компилятор программно, указывая ресурсы для встраивания, куда помещать сгенерированную сборку, зависимости и так далее. Один из сценариев здесь - использовать файл template.cs, вложить в него немного больше кода и затем скомпилировать его. Результатом является сборка (.dll или.exe или.netmodule, если хотите), полученная из этого кода. Затем вы можете загрузить эту сборку и вызвать ее, используя отражение.Создайте код, используя объектную модель документа.
Соответствующая функциональная область здесь называется "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, условия и поток управления, что угодно.
Затем вы можете скомпилировать этот класс и снова создать сборку, которую можно сохранить на диск или сохранить в памяти и динамически загружать.