Pergunta

Tenho vindo a utilizar a biblioteca ROWLEX para lidar com RDF-S. Ele é fornecido com uma ferramenta designtime GUI chamado OwlGrinder.exe que pode gerar classes C # auxiliares (NET assembléias para ser exato) dos meus ontologias OWL. Gostaria de saber se alguém sabe se eu poderia fazer o mesmo através de programação em tempo de execução.

Foi útil?

Solução

ROWLEX só se tornou open source, então agora você tem a chance de realmente olhar dentro do código de OwlGrinder.exe e copie o código de lá. No entanto, aqui está um pequeno exemplo:

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

    }

Se você deseja gerar montagens em tempo de execução, presumo que você pode querer repetir que uma e outra vez como suas demandas de usuários. Você tem que tomar cuidado aqui, porque .NET não permite que você para descarregar um conjunto. Portanto, você não pode se livrar das montagens de suas corridas anteriores. A solução é que você executar o código de geração de cada vez em um novo AppDomain que pode ser descarregado. OwlGrinder.exe faz exatamente isso, você pode querer pico dentro das MainForm.cs

Outras dicas

Sim, Sr. Lame, você pode programaticamente gerar código .NET.

Existem algumas opções.

  1. Criar o código como texto.
    Você pode compilar qualquer .cs ou .vb arquivo de origem a partir de um aplicativo. Consulte a ajuda para a classe Microsoft.CSharp.CSharpCodeProvider, para kits. Você invoca o compilador programaticamente, especificando os recursos para incorporar, onde colocar o gerado montagem, as dependências, e assim por diante. Um cenário aqui é usar um arquivo template.cs, a incorporação de um pouco de código mais para ele, e, em seguida, compilá-lo. O resultado é uma montagem (.dll ou .exe ou .netmodule se você gosta) resultante desse código. Você pode então carregar esse montagem e chamada para ele, usando a reflexão.

  2. Criar o código usando um modelo de objeto de documento.
    A área característica relevante aqui é chamado de "CodeDom" e funciona como o DOM HTML para páginas da web, exceto o modelo de objeto de documento é usado para criar código .NET. Programaticamente você construir o código, usando elementos DOM.

exemplo da coisa 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);

etc etc Você pode adicionar métodos regulares, todos os tipos de declarações no código, e assim por diante. AFAIK o CodeDom suportes coisas tudo o suporte de idiomas. Você pode fazer lambdas e expressões LINQ, condicionais e controle de fluxo, nada.

Você pode então compilar essa classe, e novamente produzir um conjunto que você pode salvar em disco ou manter na memória e carga dinâmica.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top