Pesquisar

4 de dez de 2007

Criando um assembly em tempo de execução

Vou explicar os passos básicos de como criar um pequeno assembly em tempo de execução, usando Reflection. Usando esses recursos seria possível criar um compilador para IL.

Os assemblies são feitos de: Assembly Metadata, Type Metadata, Code (IL) e Resources

  • O Assembly Metadata define propriedades como Nome e Versão do assembly
  • Type Metadata define todas as descrições de um tipo, como métodos, propriedades, nome de classe, etc
  • Code(IL) é o próprio código
  • Resources são imagens, strings, arquivos, etc

Cada assembly deve conter pelo menos um Modulo. Os módulos são uma espécie de caixa que guarda as informações sobre os Tipos.

Então vamos seguir a seguinte ordem, criamos um assembly, um modulo e um tipo, e já teremos o básico.

//namespaces necessarios
    6 using System.Reflection;
    7 using System.Reflection.Emit;


   15 //Criamos um AssemblyName

   16 AssemblyName AsyNome = new AssemblyName("MeuAssembly");

   17 //Então definimos  um novo assembly no atual AppDomain, não é possível criar um assembly a partir do próprio construtor

   18 AssemblyBuilder AsyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(AsyNome, AssemblyBuilderAccess.RunAndSave);

   19 //AssemblyBuilderAccess.RunAndSave quer dizer que podemos tanto executar esse assembly, quanto salva-lo

   20 

   21 //Criamos o modulo a partir do assembly

   22 ModuleBuilder ModBuilder = AsyBuilder.DefineDynamicModule("MeuModulo", "modulo.dll");

   23 //E um tipo a partir do modulo. Este tipo é publico e serializável, você pode atribuir várias propriedades com o operador |

   24 TypeBuilder TipoBuilder = ModBuilder.DefineType("Meutipo", TypeAttributes.Public | TypeAttributes.Serializable);

   25 

   26 

   27 //Agora podemos definir os membros do tipo, como construtores, métodos, propriedades, etc

   28 //Vamos criar um campo

   29 FieldBuilder CampoBuilder = TipoBuilder.DefineField("Campo", typeof(int), FieldAttributes.Public);

   30 

   31 //Podemos tambem salvar o assembly para uso posterior

   32 AsyBuilder.Save("modulo.dll");


Neste exemplo foi usado somente o FieldBuilder, mas  você pode criar qualquer outro membro usando os: ConstructorBuilder para construtor, EnumBuilder para enum, EventBuilder para eventos, etc

Você pode usar esse recurso para criar um software que aceite plug-ins por exemplo.

Nenhum comentário: