A los que están interesados en realizar sus propios generadores de código en .NET (C# o VB.NET), les dejo un ejemplo para utilizar Codedom (los imports mínimos son: System.CodeDom y System.CodeDom.Compiler )
Lo bueno de CodeDom es que permite generar código de manera genérica pero de implementación concreta, esto es, podemos hacer generadores de código para cualquier de los lenguajes de .NET (c++, C#, Vb.NEt, etc).
Aquí vá el ejemplo que pueden utilizar y probar, este código genera un string con el código de una clase en C# y en VB, con una propiedad llamada ID y un constructor predeterminado. Ideal para comenzar a probar y experimentar.
Dim ns As CodeNamespace 'definiendo un namespace para nuestra clase
   Private Sub GeneraClase
       'defino un namespace base
       ns = New CodeNamespace("PrimerCodeDom")
       'agrego los imports correspondientes
       'aca pueden agregar todos los imports necesarios
       ns.Imports.Add(New CodeNamespaceImport _
        ("System"))
       ns.Imports.Add(New CodeNamespaceImport _
          ("System.Diagnostics"))
       ns.Imports.Add(New CodeNamespaceImport _
          ("System.Text"))
       'creo la clase en si misma
       Dim clase As New CodeTypeDeclaration("Clase_Clientes")
       'agrego la clase a la colección de tipos
       ns.Types.Add(clase)
       'defino un campo privado
       Dim campo As New CodeMemberField("integer", "_ID")
       campo.Attributes = MemberAttributes.Private
       'agrego el miembro privado a la clase
       clase.Members.Add(campo)
       'defino un campo público
       Dim p As New CodeMemberProperty()
       ' le doy un nombre a la propiedad
       ' ID en este caso
       p.Name = "ID"
       ' lo hago público
       p.Attributes = MemberAttributes.Public
       p.Type = New CodeTypeReference("System.Int32") 'es integer
       p.HasGet = True
       p.HasSet = True 'si fuese false, sería solo lectura
       'esto que viene es obligatorio
'tengo que decirle que cosa devuelve el get de la propiedad
       p.GetStatements.Add( _
               New CodeMethodReturnStatement( _
               New CodeFieldReferenceExpression( _
               New CodeThisReferenceExpression(), "_ID")))
      'esto también es obligatorio
'tengo que decirle como se asigna el valor del set
           p.SetStatements.Add(New CodeDom.CodeAssignStatement( _
              New CodeFieldReferenceExpression( _
              New  CodeDom.CodeThisReferenceExpression, "_ID"),  _
              New CodeDom.CodePropertySetValueReferenceExpression))
       'agrego la propiedad a la clase
       clase.Members.Add(p)
       'defino un constructor público
       Dim constructor As New CodeConstructor()
       constructor.Attributes = MemberAttributes.Public
       clase.Members.Add(constructor)
        'defino los providers para los lenguajes en los que voy a generar mi clase
       Dim csProvider As New Microsoft.CSharp.CSharpCodeProvider
       Dim vbprovider As New VBCodeProvider
       'en .net 3.5 este código tira un warning por obsoleto,
'pero igual funciona perfecto.
       Dim codigo As ICodeGenerator
       codigo = vbprovider.CreateGenerator()
       Dim vbCod As String = generaCode(codigo)
       codigo = csProvider.CreateGenerator
      dim csCod as String  = generaCode(codigo)
      'en este punto, en las variables vbCod y csCod
'tienen el código de la clase correctamente generada.
   End Sub
  'metodo complementario
 Private Function generaCode(ByVal CodeGenerator As ICodeGenerator) As String
       Dim options As New CodeGeneratorOptions()
       ' defino la identación del código
       options.IndentString = Space(3)
       ' creo un StringWriter
       Dim sb As New StringBuilder()
       Dim sw As StringWriter = New StringWriter(sb)
       ' genero
       CodeGenerator.GenerateCodeFromNamespace(ns, sw, options)
       ' devuelvo el string con el código generado
       Return sb.ToString()
   End Function
Una utilidad interesante podría ser utilizar este código para generar un mapeador de clases contra tablas de una base de datos, para lo cual debemos recorrer las tablas de una base de datos, ver código SQL aquí: http://sqldata.blogspot.com/2009/01/como-obtener-todas-las-tablas-de-una.html y por cada tabla recorrer los campos con el Script SQL listado aquí: http://sqldata.blogspot.com/2009/01/como-obtener-todos-los-campos-de-una.html  y aplicar el codigo codedom correspondiente para generar un mapeador de clases contra tablas.
O sea, por cada tabla generar la clase en codedom y por cada campo generar dentro de la clase correspondiente las propiedades que necesitemos.
Con eso tienen lo necesario para generarse un mapeador de clases si se ponen manos a la obra.
Hugo Bernachea
lunes, 5 de enero de 2009
Suscribirse a:
Comentarios (Atom)
