.Net Framework 2.0 Application Development Foundation.

87
.Net Framework 2.0 Application Development Foundation

Transcript of .Net Framework 2.0 Application Development Foundation.

Page 1: .Net Framework 2.0 Application Development Foundation.

.Net Framework 2.0

Application Development Foundation

Page 2: .Net Framework 2.0 Application Development Foundation.

Contenido:

1. Framework Fundamentals2. Input/Output (I/O)3. Searching, Modifying, and Encoding

Text4. Collections and Generics5. Serialization6. Graphics7. Threading8. Application Domains and Services

Page 3: .Net Framework 2.0 Application Development Foundation.

Que es el .Net Framework

Contenido: 9. Installing and Configuring

Applications10.Instrumentation11.Application Security12.User and Data Security13.Interoperation14.Reflection15.Mail16.Globalization

Page 4: .Net Framework 2.0 Application Development Foundation.

Que es el .Net Framework1. FrameWork Fundamentals

Este capítulo busca gestionar datos en una aplicación del .Net FW usando los tipos:

• Tipos por valor• Tipos por Referencia• Atributos• Tipos Genéricos• Excepciones• Boxing & Unboxing

• Tipos por valor: Son variables que contienen sus datos directamente en lugar de contener referencias a los datos almacenados en algún lugar de la memoria (Built-in Types, User-defined types, Enumerations).

Built-in types, son los tipos base provistos por el .Net FW con los cuales, otros tipos son construidos. Ejemplo de ello son los tipos numéricos en donde la selección del tipo varia en referencia al tamaño y precisión que se espera de ello.

Page 5: .Net Framework 2.0 Application Development Foundation.

(Ver Tabla 1-1 Pag. 4)

Hay más de 300 tipos por valor en el .Net Fw, de esta forma cuando usted asigna entre variables del “tipo por valor”, el dato es copiado de una variable a la otra y almacenado en dos locaciones diferentes de la pila.

Ejemplo: (Aplicación de consola)Module Module1 Public Sub Main() Dim B As Nullable(Of Boolean) = Nothing If B.HasValue Then Console.WriteLine("b is {0}.", B.Value) Else Console.WriteLine("b is not set.") End If Console.ReadLine() End SubEnd Module

User Defined Types: También llamados estructuras, al igual que los tipos por valor, estos son almacenados en la pila y contienen sus datos directamente.

Victor
'Declarar una variable como Nullable habilita "HasValue" y "Value" para detectar si un valor ha sido ernviado.
Page 6: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Module Module1 Public Sub Main() Dim p As Person = New Person("Tony", "Allen", 32) Console.WriteLine(p) Console.ReadLine() End Sub Structure Person Public FirstName As String Public LastName As String Public Age As Integer Public Sub New(ByVal _FirstName As String, ByVal _LastName As Integer, ByVal _Age As Integer) FirstName = _FirstName LastName = _LastName Age = _Age End Sub Public Overloads Overrides Function tostring() As String Return FirstName + " " + LastName + " ,age" + Age.ToString End Function End StructureEnd Module

Las estructuras son muy similares a las clases pero mas eficientes, de este modo usted debe definir una estructura en vez de una clase, si el tipo se desarrollará mejor como un tipoi por valor que como una referencia, las estructuras se caracterizan por:

Page 7: .Net Framework 2.0 Application Development Foundation.

•Lógicamente representan un singular valor•Tienen un tamaño de instancia menor que 16 bytes•No serán cambiados luego de la creación•No serán transformados a una referencia por tipo

Enumeraciones: Son símbolos que tienen valores fijos, estas se deben usar para proveer una lista de elecciones en las clases.

Ejemplo: (Aplicación de consola)Module Module1 Public Sub Main() Dim t As Titles = Titles.Dr Console.WriteLine("{0}", t) Console.ReadLine() End Sub Enum Titles As Integer Mr Ms Mrs Dr End EnumEnd Module

Page 8: .Net Framework 2.0 Application Development Foundation.

•Tipos por Referencia: Almacenan la dirección de sus datos (también conocido como apuntador en la pila), de este modo representan la dirección de los datos en vez de los datos por sí mismos. En la práctica asignar una variable por referencia a otra no copia los datos; en lugar de ello simplemente crea una segunda copia de la referencia.

Ejemplo: (Aplicación de consola)Module Module1 Public Sub Main() Dim n1 As Numbers = New Numbers(0) Dim n2 As Numbers = n1 n1.Val += 1 n2.Val = 2 Console.WriteLine("n1={0}, n2={1}", n1, n2) Console.ReadLine() End Sub Structure Numbers Public Val As Integer Public Sub New(ByVal _Val As Integer) Val = _Val End Sub Public Overloads Overrides Function tostring() As String Return Val.ToString End Function End StructureEnd Module

Victor
El código muestra "n1=1, n2=2" porque las estructuras son "Tipos por valor" y copia un resultado en dos distintass variables; sin embargo si se cambia la declaración de "Structure" a "Class" en la misma aplicación obtendremos "n1=3, n2=3" dado que tendremos ahora un "tipo por referencia" modificando todas las copias de las variables instanciadas.
Page 9: .Net Framework 2.0 Application Development Foundation.

•Construyendo Clases: En lenguages orientados a objetos el grueso del trabajo debe ser desarrollado dentro de objetos requeriendo construir clases cada c/u de ellos con múltiples prepiedades y métodos usados para desarrollar tareas relacionades al objeto.

Herencia. La herencia en .Net Fw tiene miles de clases y cada classe tiene diferentes métodos y propiedades, mantener el seguimiento de todos ellos sería imposible si no fuera por la consistencia, la cual a su vez es posible gracias a la herencia y las interfaces. La herencia se utiliza para crear nuevas clases a partir de unas ya existentes.

Ejemplo: (Fragmento de código)Class DerivedException Inherits System.ApplicationException Public Overrides ReadOnly Property Message() As String Get Return "Un Error ocurrío en la aplicación" End Get End PropertyEnd Class

Interfaces. Tambien conocidas como los contratos, definen un set de miembros comunes para todas las clases que la interface debe proveer.

Page 10: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Fragmento de código)Interface Imessage 'Envia el mensaje. Retorna True si es exitoso. Falso de otra forma Function Send() As Boolean 'El mensaje a enviar Property Message() As String 'Dirección a enviar el mensaje Property Addres() As String End Interface

Class EmailMessage Implements Imessage

Public Property Addres() As String Implements Imessage.Addres Get End Get Set(ByVal value As String) End Set End Property

Public Property Message() As String Implements Imessage.Message Get End Get Set(ByVal value As String) End Set End Property

Public Function Send() As Boolean Implements Imessage.Send End Function End Class

Victor
Al crear una clase que implemente la interface "Imessage", automáticamente se crearán las propiedades "Send", "Message" y Addres".
Page 11: .Net Framework 2.0 Application Development Foundation.

•Generics. Son parte de los tipos en el .Net Fw que permiten definir un tipo mientras dejan algunos detalles inespecificados. Los tipos Generics ofrecen mayores ventajas sobre la clase “Object” como:

El compilador en los tipos “Object” no puede detectar errores cuando se hacen transformaciones de la clase object o hacia dicha clase. Adicionalmente se pueden especificar constrains para limitar las clases usadas en Generics, habilitando el compilador para detectar tipos incompatibles.

Mejoran el performance, ya que las conversiones “boxing” y el “unboxing” disminuyen el rendimiento.

Ejemplo: (Aplicación de consola) Module Module1 Public Sub Main() 'Adicione un double a un entero usando la clase generica "Gen" Dim gb As New Gen(Of Double, Integer)(10.125, 2005) 'Adicione un Double y un entero usando la clase "Obj" Dim Ob As Obj = New Obj(10.125, 2005) Console.WriteLine(CType(Ob.V1, Integer) + CType(Ob.V2, Integer)) Console.ReadLine() End Sub

Victor
Al hacer de los tipos "Object" el compilador no detecta que la primera variable era un "Double" y pierde su parte decimal arrojando como resultado "2015" en vez de "2015.125"
Page 12: .Net Framework 2.0 Application Development Foundation.

Class Obj Public V1 As Object Public V2 As Object Public Sub New(ByVal _V1 As Object, ByVal _V2 As Object) V1 = _V1 V2 = _V2 End SubEnd Class

Class Gen(Of T, V) Public V1 As T Public V2 As V Public Sub New(ByVal _V1 As T, ByVal _V2 As V) V1 = _V1 V2 = _V2 End Sub End Class

End Module

Eventos. La mayoría de los proyectos son no lineales; en los formularios se debe esperar a que el usuario haga click o presione una tecla para responder al evento. En las aplicaciones de servidor se deben esperar los request, todas estas capacidades son provistas por el .Net FW mediante los eventos.

Dicho de otra forma un evento es un mensaje enviado por un objeto para indicar la concurrencia de una acción; la acción puede ser un click ó puede ser lanzada por alguna otra lógica.

Page 13: .Net Framework 2.0 Application Development Foundation.

El objeto que causa el evento es conocido como “event sender” y el objeto que captura el evento y responde a este es llamado “event receiver”. En la comunicación de eventos la clase “event sender” no conoce cual objeto ó método recibirá “manejará” el evento provocado, por tanto es necesario un intermediario entre la fuente y el receptor. El .Net FW define un tipo especial (Delegado) que provee la funcionalidad de apuntador de funciones.

Delegado. Un delegado es una clase que puede mantener una referencia a un método. A diferencia de otras clases el delegado tiene una forma y esta protege la referencia sólo a métodos que coinciden con esta firma, un delegado es un equivalente a un apuntador de funciones seguro.

Ejemplo: (Fragmento de código)Public Delegate Sub AlarmEventHandler (Sender as Object, e as EventArgs)

La firma estándar de un delegado manejador de eventos define un método que no retorna un valor, mientras el primer parámetro es del tipo Object y se refiere a la instancia que causa el evento, el segundo parámetro es derivado del tipo “EventArgs” manteniendo los datos del evento.

Page 14: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación Windows)Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) End Sub

Public Sub New() ' Llamada necesaria para el Diseñador de Windows Forms. InitializeComponent() ' Agregue cualquier inicialización después de la llamada a InitializeComponent(). AddHandler Me.Button1.Click, AddressOf Me.Button1_Click End SubEnd Class

La firma estándar de un delegado manejador de eventos define un método que no retorna un valor, mientras el primer parámetro es del tipo Object y se refiere a la instancia que causa el evento, el segundo parámetro es derivado del tipo “EventArgs” manteniendo los datos del evento.

•Conversión entre Tipos: Por defecto VB permite conversiones implícitas entre tipos, es decir conversiones que pierden precisión, para modificar este comportamiento se debe: (Adicionar “Option Strictict On” en el inicio de cada fichero ó en VS seleccionar Project->Properties->Compile->Option Strict On lo cual aplicará para todo el proyecto).

Victor
Agregar un Formulario.
Victor
Quitar el manejador del evento click "Handles Button1.Click" que se crea por defecto.
Victor
Objeto Delegado que manejarä el evento click. Al quitar ó comentariar el manejador de eventos y ejecutar el proyecto se observa que al hacer click no existe un método que maneje el evento.
Page 15: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Module Module1 Public Sub Main() Dim i As Integer = 1 Dim d As Double = 1.0001 d = i Console.WriteLine("La conversión es permitida, d=,{0}", d) Console.ReadLine() End Sub

End Module

2.Input/Output (I/O)

Este capítulo pretende enseñar como trabajar con el sistema input/output dentro del .Net Fw, las bases incluyen acceso a archivos, carpetas en el sistema, trabajar con streams y con el almacenamiento.

•Navegando en el Sistema de Archivos. Una de las tareaas más comunes es trabajar con el sistema de archivos, compartir información en undades, carpetas y archivos. El responsable de estas tareas es el nameSpace denominado System.IO, de este modo de derivan dos de sus clases: (FileInfo y DirectoryInfo).

(Ver tabla 2-1 Pag. 70)(Ver tabla 2-2 Pag. 70)

Victor
La conversión es permitida y erronea!.
Victor
Crear la aplicación sin el "Option Strict On".
Page 16: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación consola)Imports System.IOModule Module1 Public Sub Main() Dim ourDir As DirectoryInfo = New DirectoryInfo("C:\windows") Console.WriteLine("Directory: {0}", ourDir.FullName) For Each file As FileInfo In ourDir.GetFiles Console.WriteLine("File:{0}", file.Name) Next Console.ReadLine() End SubEnd Module

•Leyendo y Escribiendo Archivos:Streams. Los Streams son una forma común para tratar el acceso a datos secuenciales y randómicos dentro del .Net Fw, las clases de streams más comunes son:

-FileStream (System.Io)-MemoryStream (System.Io)-CryptoStream (System.Security)-NetWorkStream (System.Net)-GzipStream (System.Compression)

Page 17: .Net Framework 2.0 Application Development Foundation.

El denominador común para estos streams es que todos trabajan los datos como un flujo.

FileStream:

StreamReader. Provee la funcionalidad básica para leer datos de un stream, de este modo al abrir un archivo siempre es conveniente preguntar a la clase “File” para la apertura del stream especificando el camino al archivo.

Ejemplo (Aplicación de consola)Imports System.IOModule Module1 Public Sub Main() Dim thefile As FileStream = File.Open("C:\Notas.txt", FileMode.Open, FileAccess.Read) Dim rdr As StreamReader = New StreamReader(thefile) Console.Write(rdr.ReadToEnd) rdr.Close() thefile.Close() Console.ReadLine() End SubEnd Module

StreamWriter. Esta clase provee la funcionalidad básica para escribir datos de un stream, recordando siempre utilizar la clase “File” para la apertura de archivos.

Victor
Crear un archivo en la raiz del C:\, y llamarlo "Notas.txt".
Victor
Para hacerlo aún más fácil la clase "File" soporta métodos para lectura, en los anteriores ejemplos se debío crear un FileStream y un StreamReader; en vez de ello la clase File soporta crear directamente un StreamReader con el método "OpenText".Complemento al Ejemplo: Dim rdr2 As StreamReader = File.OpenText("c:\notas.txt") Console.Write(rdr2.ReadToEnd) rdr2.Close()
Page 18: .Net Framework 2.0 Application Development Foundation.

Ejemplo (Aplicación de consola)Imports System.IOModule Module1 Public Sub Main() Dim thefile As FileStream = File.Open("C:\Notas.txt", FileMode.Open, FileAccess.Read) Dim rdr As StreamReader = New StreamReader(thefile) Console.Write(rdr.ReadToEnd) rdr.Close() thefile.Close() Console.ReadLine() End SubEnd Module

StreamWriter. Esta clase provee la funcionalidad básica para escribir datos de un stream, recordando siempre utilizar la clase “File” para la apertura de archivos.Ejemplo: (Aplicación de consola)Imports System.IOModule Module1 Public Sub Main() Dim thefile As FileStream = File.Create("C:\SomeFile.txt") Dim writer As StreamWriter = New StreamWriter(thefile) writer.WriteLine("Hello") writer.Close() thefile.Close()

Dim writer2 As StreamWriter = File.CreateText("C:\somefile2.txt") writer2.WriteLine("Hello") writer2.Close() Console.ReadLine() End SubEnd Module

Victor
Con el objeto FileStream una vez creado, se puede enviar datos al archivo mediante el StreamWriter.
Victor
Puedo crear directamente el StreamWriter.
Page 19: .Net Framework 2.0 Application Development Foundation.

MemmoryStream. Provee la funcionalidad para crear streams en memoria debido a que normalmente se hacen cambios sobre los streams antes de almacenarlos.

Ejemplo (Aplicación de consola)Imports System.IOModule Module1 Public Sub Main() Dim memstrm As New MemoryStream Dim writer As New StreamWriter(memstrm) writer.WriteLine("Hello") writer.WriteLine("GoodBye") writer.Flush() Dim theFile As FileStream = File.Create("C:\inmemmory.txt") memstrm.WriteTo(theFile) writer.Close() theFile.Close() memstrm.Close() Console.ReadLine() End SubEnd Module

BufferedStream. Esta clase provee la funcionalidad para agrupar streams para mejorar el performance memorizando la lectura y escritura a travez del stream. El BufferStream envuelve otro objeto stream paraa permitir escribir lo que ocurra al buffer y solo cuando el buffer es limpiado, los datos son realmente empujados al stream subyacente.

Page 20: .Net Framework 2.0 Application Development Foundation.

Ejemplo (Aplicación de consola)Imports System.IOModule Module1 Public Sub Main() Dim NewFile As FileStream = File.Create("c:\test.txt") Dim buffered As New BufferedStream(NewFile) Dim Writer As New StreamWriter(buffered) Writer.WriteLine("Algún dato") Writer.Close() Console.ReadLine() End SubEnd Module

•Comprimiendo Streams. En esta lección se busca trabajar con streams para ahorrar ancho de banda o comprimir espacio, en el .Net Fw existe el namespace “System.Io.Compression” que a su vez expone dos métodos para comprimir datos (GzipStream y DeflateStream).

La compresión de Streams es un poco diferente que los recursos anteriores debido a que en vez de escribir a un recurso directamente, este escribe a otro stream en formato comprimido.

Victor
Incluye información en la cabecera que ayuda en la descompresión.
Page 21: .Net Framework 2.0 Application Development Foundation.

Ejemplo (Aplicación de consola)Imports System.IOImports System.IO.CompressionModule Module1

Sub Main()

CompressFile("c:\test.txt", "c:\test.txt.gz") DecompressFile("c:\test.txt.gz", "c:\test2.txt")

ComprimirArchivo("c:\test.txt", "c:\test.txt.gz") DesComprimirArchivo("c:\test.txt.gz", "c:\test2.txt") End Sub

Sub CompressFile(ByVal inFilename As String, ByVal outFilename As String) Dim sourceFile As FileStream = File.OpenRead(inFilename) Dim destFile As FileStream = File.Create(outFilename) Dim compStream As New GZipStream(destFile, CompressionMode.Compress) Dim theByte As Integer = sourceFile.ReadByte() While theByte <> -1 compStream.WriteByte(CType(theByte, Byte)) theByte = sourceFile.ReadByte() End While compStream.Flush() : compStream.Close() sourceFile.Close() destFile.Close()

End Sub

Victor
Los métodos CompressFile & DecompressFile son ineficientes porque leen de byte a byte y aumentan el tamaño del archivo de salida.
Victor
Los métodos ComprimirArchivo y DescomprimirArchivo recorren el stream en bloques de 1024 bytes, de esta manera no agrego tantos encabezados al archivo comprimido y obtengo un mejor resultado.
Page 22: .Net Framework 2.0 Application Development Foundation.

Sub DecompressFile(ByVal inFilename As String, ByVal outFilename As String) Dim sourceFile As FileStream = File.OpenRead(inFilename) Dim destFile As FileStream = File.Create(outFilename) Dim compStream As New GZipStream(sourceFile, CompressionMode.Decompress, True) Dim theByte As Integer = compStream.ReadByte() While theByte <> -1 destFile.WriteByte(CType(theByte, Byte)) theByte = compStream.ReadByte() End While compStream.Flush() : compStream.Close() sourceFile.Close() destFile.Close()End Sub

Const BUFFER_SIZE As Integer = 1024 Sub ComprimirArchivo(ByVal inFilename As String, ByVal outFilename As String) ' Open the input file as a stream Using sourceFile As New FileStream(inFilename, FileMode.Open, FileAccess.Read) ' Create the output stream Using destFile As New FileStream(outFilename, FileMode.Create, FileAccess.Write) ' Create the GZip stream, attached to the output stream. Using compStream As New GZipStream(destFile, CompressionMode.Compress, False) Dim buff(BUFFER_SIZE) As Byte ' Read input and write to compression stream. Dim bytesRead As Integer = sourceFile.Read(buff, 0, BUFFER_SIZE) While bytesRead <> 0 compStream.Write(buff, 0, bytesRead) bytesRead = sourceFile.Read(buff, 0, BUFFER_SIZE) End While End Using End Using End UsingEnd Sub

Page 23: .Net Framework 2.0 Application Development Foundation.

Sub DesComprimirArchivo(ByVal inFilename As String, ByVal outFilename As String) ' open input stream Using sourceFile As New FileStream(inFilename, FileMode.Open, FileAccess.Read) ' Create the GZipStream attached to the input Using compStream As New GZipStream(sourceFile, CompressionMode.Decompress, False) ' Create the output stream Using destFile = New FileStream(outFilename, FileMode.Create, FileAccess.Write) Dim buff(BUFFER_SIZE) As Byte ' Read compressed data and write uncompressed Dim bytesRead As Integer = compStream.Read(buff, 0, BUFFER_SIZE) While bytesRead <> 0 destFile.Write(buff, 0, bytesRead) bytesRead = compStream.Read(buff, 0, BUFFER_SIZE) End While End Using End Using End Using End SubEnd Module

3.Buscando, Modificando y Encriptando Texto.

Procesar texto es una de las tareas más comunes, las entradas de los usuarios normalmente son hechas en texto y se hace necesario validarlas, sanearlas y reformatearlas. Este capítulo describe como usar expresiones regulares para validar y extraer datos. Adicionalmente este capítulo describe diferentes tipos de codificación usadas para archivos de texto.

Page 24: .Net Framework 2.0 Application Development Foundation.

•Formando Expresiones Regulares:Una expressión regular es un set de caracteres que pueden ser comparados con un string para determinar si el string cumple con los requerimientos del formato específico. Tambien se usan expresiones regulares para extraer porciones de texto o reemplazarlo.

Ejemplo: (Aplicación de consola)Imports System.Text.RegularExpressionsNamespace TestRegExp Class Class1

Shared Sub main(ByVal args() As String) If Regex.IsMatch(args(1), args(0)) Then Console.WriteLine("Las entradas coinciden.") Else Console.WriteLine("Las entradas no coinciden") End If End Sub End ClassEnd Namespace

Extraer coincidencias de Datos. En lugar de simplemente determinar si un string coincide con una aproximación, es posible extraer datos de un string; para ello se hace uso del namespace “System.Text.RegularExpression” y su biblioteca de clase “Regex” que representa una expresión regular inmutable.

Victor
Crear una aplicación de consola y llamarla "TestRegExp". Luego correr la aplicación desde "Dos" y ejecutar el siguiente comando:c:\"Dir del Proyecto"\>TestRegExp ^\d{5}$ 12345La expresion regular traduce:^ Comienzo\d Sólo dígitos numéricos{5} Coinciden exactamente 5 carácteres$ Final de la entrada
Page 25: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.Text.RegularExpressionsClass Class1

Shared Sub main(ByVal args() As String) Dim input As String = "Company Name: Contoso, INC." Dim m As Match = Regex.Match(input, "Company Name: (.*$)") Console.WriteLine(m.Groups(1)) Console.ReadLine End SubEnd Class

Reemplazar SubStrings usando Expresiones Regulares. Es posible usar expresiones regulares para desarrollar reemplazos tan complejos como sea posible, mediante el método “Replace”.

Ejemplo: (Aplicación de consola)Imports System.Text.RegularExpressionsNamespace Regular Class Replace

Shared Sub main(ByVal MDY() As String) Console.WriteLine(Regex.Replace(MDY(0), "\b(?<month>\d{1,2})/(?<day>\d{1,2})/(?<year>\d{2,4})\b", "${day}-${month}-${year}")) Console.ReadLine() End Sub End ClassEnd Namespace

Victor
Representa los resultados de una expresión regular.
Victor
Representa una expresión regular inmutable.
Victor
Ejecutar la aplicacion desde el "DOS" así:Regular.exe "12/30/2008" lo cual imprimirá "30/12/2008".
Victor
Crear una aplicación de consola y llamarla "Regular.exe".
Page 26: .Net Framework 2.0 Application Development Foundation.

•Encoding & Decoding:Cada string y archivo de texto es codificado usando una de muchas diferentes estadares de codificación. La mayoría del tiempo el .Net FW maneja el encoding automáticamente; sin embargo existen ocasiones en las que puede ser necesario manualmente controlar la codificación tales como:

-Interoperabilidad con sistemas legados-Leer o escribir texto a otros lenguajes-Crear páginas HTML-Generar manualmente emails

La ASCII organismo encargado de la codificación en USA asignó 7 bits para la codificación inglesa contenidos desde el 0~127; sin embargo los alfabetos no ingleses requerían ampliar la codificación de 7 a 8 bits utilizando entonces los valores del 128 al 255. De modo que traducir documentos entre lenguages conllebaba a un problema, por ello la ANSI definió las Paginas de Código que tienen por estándar a la codificación ASCII desde los valores 0~127 y de forma específica los valores del 128~255. Las paginas de código son una lista de códigos de caracteres seleccionados en un orden certero.

Page 27: .Net Framework 2.0 Application Development Foundation.

Las páginas de código son usualmente definidas para soportar lenguages específicos o grupos de lenguajes que comparten sistemas de escritura común.Hoy en día los tipos de codificacion ASCII e ISO8859 están siendo reemplazados por el unicode, el cual es una masiva página de códifos con 10.000 caracteres que soportan la mayoria de lenguages y scripts incluyendo latín, griego, hebreo, chino, etc…

El .Net FW soporta los siguientes tipos de codificación:-Unicode UTF-32 caracteres como secuencias de 32 bits

enteros-Unicode UTF-16 caracteres como secuencias de 16 bits

enteros-Unicode UTF-8 interoperable con ASCII-ASCII codifica alfabetos latinos-ANSI soporta un amplio rango de ANSI/ISO encoding

Page 28: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.TextImports System.IOModule Regular Sub main() Dim swUtf7 As StreamWriter = New StreamWriter("UTF7.txt", False, Encoding.UTF7) swUtf7.WriteLine("Hello, world!") swUtf7.Close() Dim swUtf8 As StreamWriter = New StreamWriter("utf8.txt", False, Encoding.UTF8) swUtf8.WriteLine("Hello, world!") swUtf8.Close() Dim swUtf16 As StreamWriter = New StreamWriter("utf16.txt", False, Encoding.Unicode) swUtf16.WriteLine("Hello, World!") swUtf16.Close() Dim swUtf32 As StreamWriter = New StreamWriter("UTF32.txt", False, Encoding.UTF32) swUtf32.WriteLine("Hello World!") swUtf32.Close() Console.ReadLine() End SubEnd Module

4.Colecciones y Generics.Las colecciones son clases usadas para agrupar y gestionar objetos que permiten (almacenar, observar e iterar) sobre colecciones de objetos. Dicho de otra forma las colecciones empiezan donde los arrays finalizan.

NameSpace “System.Collections”

Victor
Utf8 y Utf16 son compatibles con el NotePad, por tanto la información es legible.
Page 29: .Net Framework 2.0 Application Development Foundation.

Tipos de Collecciones:

Gestionar datos usando colecciones especializadas es mediante el namespace “System.Collection.Specialized”

Colecciones Colecciones

ArrayList DictionaryBase & DictionaryEntry

Collection Interface Comparer

Iterators Queue

HashTable SortedList

Collectionbase & ReadOnlyCollectionBase

BitArray

Stack

Colecciones Especializadas

Specialized String

Specialized Dictionary

NameValueCollection

CollectionUtil

BitVector32 structure & BitVector32.section

Page 30: .Net Framework 2.0 Application Development Foundation.

Para mejorar el tratamiento de los tipos seguros y el performance en las aplicaciones tenemos el uso de Generics mediante el namespace “System.Collection.Generic”:

•Coleccionando Items de Datos:Tipos de Colección. El .Net FW como se mencionó anteriormente soporta varios tipos de colecciones , en la mayoría de los casos el FW provee una colección para almacenar los datos correctamente.

Colecciones Generic

Generic Dictionary

Generic Comparer & Generic EqualityComparer

Generic KeyValuePair

Generic List, Generic List.Enumerator, Generic.SortedList

Generic Queue, Generic Queue.Enumerator

Generic SortedDictionary

Generic LinkedList

Generic Stack, Generic Stack Enumerator

Page 31: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.TextImports System.IOModule Collections Sub main() Dim Coll As New ArrayList Dim s As String = "Hello" Coll.Add(s) Coll.Add(50) Coll.Add(New Object)

Dim anArray() As String = {"more", "or", "less"} Coll.AddRange(anArray) Dim anotherArray() As Object = {New Object(), New ArrayList()} Coll.AddRange(anotherArray)

Coll.Insert(3, "Hey All") Dim morestrings() As String = {"goodnight", "see ya"} Coll.InsertRange(4, morestrings)

Coll(3) = "Set value"

Coll.Remove("Hello") Coll.RemoveAt(1) Coll.RemoveRange(2, 4) Console.ReadLine() End SubEnd Module

Victor
Adiciono Items individuales a la colección.
Victor
se pueden agregar incluso arrays a la colección.
Victor
"Add" y "AddRange" agregan items al final de la colección, ello debido a que la colección ArrayList es una colección dinámica.
Victor
Se pueden insertar objetos en ubicaciones específicas.
Victor
Se puede utilizar el indice para establecer un valor en una posición específica, que a diferencia de "Insert" este sobreescribe el valor.
Victor
Remueve según indice específico.
Victor
Remueve un conjunto de items, desde la posición (2) indicando el No de elementos a remover.
Page 32: .Net Framework 2.0 Application Development Foundation.

Iterando sobre Items. Una colección no s muy útil a menos que se pueda recorre a través de los ítems. El ArrayList soporta un índice numérico que permite escribir simple código de iteración.

Ejemplo: (Aplicación de consola)Imports System.TextImports System.IOModule Collections Sub main() Dim Coll As New ArrayList Dim s As String = "Hello" Coll.Add(s) Coll.Add(50) Coll.Add(New Object)

For x As Integer = 0 To Coll.Count - 1 Step +1 Console.WriteLine(Coll(x)) Next Console.ReadLine() End SubEnd Module

ArrayList también soporta la interface IEnumerable que permite el uso de un Enumerador para acceder a la lista y avanzar en una dirección.

Victor
ArrayLsit también soporta la interface IEnumerable que permite el uso de un Enumerador para acceder a la lista y avanzar en una dirección.
Page 33: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.TextImports System.IOModule Collections Sub main() Dim Coll As New ArrayList Dim s As String = "Hello" Coll.Add(s) Coll.Add(50) Coll.Add(New Object)

For Each item As Object In Coll Console.WriteLine(item) Next Console.ReadLine() End SubEnd Module

•Trabajando con Listas Secuenciales:A menudo las colecciones son un set de objetos que necesitan ser tratados en una forma ordenada. En lugar de usar colecciones como ArrayList el .Net Fw expone 2 clases cuyo trabajo es almacenar datos como una lista y simplemente permitir el acceso a estos objetos como ellos sean necesarios. Las clases Queue y Stack son usadas para almacenar datos en una forma secuencial.

Page 34: .Net Framework 2.0 Application Development Foundation.

The Queue Class. Es una colección permite en sus datos; al primero en entrar ser en primero en salir (FIFO), Queue trata las operaciones de acceso y remoción de ítems en una sola vía, difiriendo de ArrayList ya que las operaciones de acceso y remoción de ítems están combinadas en una sola acción.

Ejemplo: (Aplicación de consola)Imports System.TextImports System.IOModule Collections Sub main() Dim q As New Queue q.Enqueue("Primero") q.Enqueue("Segundo") q.Enqueue("Tercero") q.Enqueue("Cuarto") While q.Count > 0 Console.WriteLine(q.Dequeue) End While Console.WriteLine("No de elementos: {0}", q.Count) Console.ReadLine() End SubEnd Module

La Clase Stack. En contraste a “Queue” la clase Stack permite al interior de sus ítems; último en entrar ser el primero en salir, soportando los métodos “Pop” y “Push”.

Victor
Al aplicar el método "Dequeue" sobre la colección, no queda ningún elemento restante.
Page 35: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.TextImports System.IOModule Collections Sub main() Dim q As New Stack q.Push("Primero") q.Push("Segundo") q.Push("Tercero") q.Push("Cuarto") While q.Count > 0 Console.WriteLine(q.Pop) End While Console.WriteLine("No de elementos: {0}", q.Count) Console.ReadLine() End SubEnd Module

•Trabajando con Diccionarios.Los diccionarios son colecciones que almacenan lista de (clave/valor) ó pares que permiten mirar valores basados en su clave. Mas conocido como la clase “HashTable” permiten el mapeo (clave/valor) y a diferencia de las anteriores colecciones, siempre se esperan dos piezas de información para adicionar un item a la colección (la clave y el valor).

Page 36: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.TextImports System.IOModule Collections Sub main() Dim emaillookup As New Hashtable emaillookup("[email protected]") = "Bishop, Scott" emaillookup("[email protected]") = "Hess, Christian" emaillookup("[email protected]") = "jump, Dan" For Each entry As DictionaryEntry In emaillookup Console.WriteLine(entry.Value) Next entry Console.ReadLine() End SubEnd Module

•Usando colecciones Especializadas.Las tres primeras lecciones tratan sobre el almacenamiento de cualquier tipo de objeto en .Net, de modo que a menudo se debe emplear conversiones para operar sobre ellas. Para ello existe el namespace llamado “System.Collection.Specialized” que abarca tipos de datos especializados.

Trabajando con Bits. En muchas ocasiones se necesitará tratar con datos en un set de expresiones booleanas, esto es posible con colecciones las “BitArray” & “BitVector32”. BitArray es una colección que puede almacenar valores booleanos, soportando operaciones como (And, Not, Or, Etc..)

Victor
Prodriamos también imprimir las claves de la collección, mediante "entry.Key".
Page 37: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.TextImports System.IOModule Collections Sub main() Dim bits As BitArray = New BitArray(3) bits(0) = 1 bits(1) = 1 bits(2) = 1

Dim SecondBits As BitArray = New BitArray(3) SecondBits(0) = 0 SecondBits(1) = 1 SecondBits(2) = 0

Dim AndBits As BitArray = bits.And(SecondBits) For Each bit As Boolean In AndBits Console.WriteLine(bit) Next Console.ReadLine() End SubEnd Module

•Colecciones Genericas “Generics”.La collección más usada “ArrayLisst” intenta cubrir la mayoria de necesidaddes ya que cualquiera de sus miembros es un objeto, operaciones como agrupar, ordenar e indexar están todas cubiertas, pero a su vez introduce un nuevo problema; ya que si el usuario solo desea almacenar un tipo en concreto “Cómo solo enteros” tendremos un dificulta.

Victor
Podriamos aplicar la operación "OR" y el resultado sera de "111" ó "True" en todas las operaciones.
Page 38: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.TextImports System.IOModule Collections Sub main() Dim myInts As New ArrayList myInts.Add(1) myInts.Add(2) myInts.Add(3) myInts.Add("4")

For Each i As Object In myInts Dim number As Integer = CType(i, Integer) Console.WriteLine(number) Next Console.ReadLine() End SubEnd Module

Para hacer el control de tipos posible .Net FW creó “Generics”, los cuales son tipos que toman otros nombres genericos para definirlos como un tipo. Entonces en vez de implementar una colección que es fuertemente tipada a un especifico tipo, con “Generics” se puede asociar cualquier tipo.

Victor
Error inducido, pro no habría ninguna excepción.
Page 39: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Public Class MyList(Of T) Implements ICollection Implements IEnumerable

Private _InnerList As ArrayList = New ArrayList Public Sub Add(ByVal val As T) _InnerList.Add(val) End Sub Default Public ReadOnly Property Item(ByVal index As Integer) As T Get Return CType(_InnerList(index), T) End Get End Property#Region "Miembros de Icollection“#End RegionEnd Class

Option Explicit OnOption Strict OnImports System.IOImports System.CollectionsModule Collections Sub main() Dim myIntList As New MyList(Of Integer)() myIntList.Add(1) myIntList.Add("4")

Dim MyStringList As New MyList(Of String)() MyStringList.Add("1") MyStringList.Add(2) End SubEnd Module

Victor
Crear un archivo aparte para esta clase.
Victor
Estos miembros los crea automáticamente .Net, al implementar "ICollection" e "IEnumerable".
Victor
Crear un archivo aparte para este modulo. Esta aplicación no compilará porque generará exepciones.!!!!!!!
Victor
Aca abrá una excepción, ya que es una collección de Enteros.
Victor
Esto generará otra excepción porque es una collección de Strings.
Page 40: .Net Framework 2.0 Application Development Foundation.

5. Serialización:Muchas aplicaciones necesitan almacenar o transferir datos

almacenados en objetos, para realizar estas tareas de convertir objetos a binario, SOAP ó XML se creó la serialización. La representación de dicho objeto ó su conversión a otro formato es llamada serialización.

La serialización esta implementada en “System.Runtime.Serialization” dicho proceso almacenar, trasmitir y después recrear los objetos; el proceso de recrear o convertir la secuencia de bytes en un objeto es llamado DesSerializar.

Ejemplo: (Aplicación de consola)Imports System.IOImports System.Runtime.SerializationImports System.Runtime.Serialization.Formatters.BinaryModule Serializar Sub main() Dim dataIn As String = "Este texto está almacenado en un archivo" Dim fsIn As FileStream = New FileStream("SerializedString.Data", FileMode.Create) Dim bfIn As BinaryFormatter = New BinaryFormatter bfIn.Serialize(fsIn, dataIn) fsIn.Close()

Page 41: .Net Framework 2.0 Application Development Foundation.

Dim fsOut As FileStream = New FileStream("SerializedString.Data", FileMode.Open) Dim bfOut As BinaryFormatter = New BinaryFormatter Dim dataOut As String = "" dataOut = CType(bfOut.Deserialize(fsOut), String) Console.WriteLine(dataOut) Console.ReadLine() End SubEnd Module

•Serialización XML.Xml es un formato estándar para almacenar información legible, además de ello es fácilmente procesado por Pc’s pudiendo almacenar cualquier tipo de datos como documentos, fotos, música, archivos binarios, etc…El .Net FW soporta librerias para leer y escribir archivos xml como “System.Xml.Serialization”, de este modo se puede escribir cualquier objeto a archivos de texto para luego recuperarlos.

¿Porque usar serialización XML?. Se utiliza serialización xml cuando necesite intercambiar un objeto con una aplicación que no este basada en el .Net Fw, lo caul nos permite adaptarnos a los estándares.

Page 42: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.IOImports System.xml.SerializationModule Serializar Sub main() 'Dim dataIn As String = "Este texto está almacenado en un archivo" Dim fsIn As FileStream = New FileStream("SerializedDate.xml", FileMode.Create) Dim xsIn As XmlSerializer = New XmlSerializer(GetType(DateTime)) xsIn.Serialize(fsIn, System.DateTime.Now) fsIn.Close()

Dim fsOut As FileStream = New FileStream("SerializedDate.xml", FileMode.Open) Dim xsOut As XmlSerializer = New XmlSerializer(GetType(DateTime)) Dim previostime As DateTime = CType(xsOut.Deserialize(fsOut), DateTime) fsOut.Close() Console.WriteLine(("Day: " + previostime.DayOfWeek.ToString + (" Time: " + previostime.TimeOfDay.ToString))) Console.ReadLine() End SubEnd Module

6.Gráficos:El uso de gráficos enriquece las interfaces en el .Net Fw, incluyendo herramientas que permiten dibujar lineas, text, formatos, etc… En este capítulo se discute como crear gráficos e imágenes usando el namespace “System.Drawing”.

Victor
Typos de datos que vamos a serializar, podemos cambiarlo luego por "String" si vamos a serializar texto.
Victor
Cadena de datos a serializar.
Victor
Tipo de datos en la que vamos a Desserializar.
Page 43: .Net Framework 2.0 Application Development Foundation.

Trabajando con Imágenes.A menudo los desarrolladores necesitan trabajar con imágenes, tareas como (crear, editar ó modificar); para ello el .Net Fw provee herramientas para trabajar con una variedad de formatos.

La clase Image & Bitmap. La clase “System.Drawing.Image” es abstracta, pero aún así se pueden crear instancias de la clase usando “Image.FromFile” & Image.FromStream. Sumado a ello existen clases que heredan de “Image” como son:

-System.Drawing.Bitmap-> Para imágenes estáticas.-System.Drawing.Imagin.Metafile->Para imágenes animadas

Ejemplo: (Aplicación Windows)Imports System.DrawingPublic Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim I As Image = Image.FromFile("c:\Ruta\Imagen.jpeg") PictureBox1.BackgroundImage = I End SubEnd Class

Victor
Agregar como referencia al proyecto, el assembly "System.Drawing".Agregar un control "PictureBox".
Page 44: .Net Framework 2.0 Application Development Foundation.

Crear y guardar imágenes. Para crear una nueva imagen, se crea una instancia de la clase bitmap, de la misma forma “bitmap” ofrece el método “save” que tiene sobrecragas para especificar el formato de la imagén a guardar (bmp, emf, jpteg, etc...)

Ejemplo: (Aplicación Windows)Imports System.DrawingImports System.Drawing.Drawing2DImports System.Drawing.ImagingPublic Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim Bm As Bitmap = New Bitmap(600, 600) Dim G As Graphics = Graphics.FromImage(Bm) Dim B As Brush = New LinearGradientBrush(New Point(1, 1), New Point(600, 600), Color.White, Color.Red) Dim Points As Point() = New Point() {New Point(10, 10), New Point(77, 500), New Point(590, 100), New Point(250, 590), New Point(300, 410)} G.FillPolygon(B, Points) Bm.Save("bm.jpeg", ImageFormat.Jpeg) End SubEnd Class

Iconos. Los iconos son mapas de bits transparentes que son usados por windows, el .Net Fw provee un set de iconos en la clase “System.Icons” incluyendo icones de exclamación, información, etc..

Victor
Agregar el assembly "System.Drawing" al proyecto.
Victor
Agregar un formulario al proyecto.
Page 45: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación Windows)Imports System.Drawing.Drawing2DImports System.DrawingPublic Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim G As Graphics = Me.CreateGraphics G.DrawIcon(SystemIcons.Question, 40, 40) End SubEnd Class

El .Net Fw da el control sobre la alineación y dirección del texto usando la clase “String.Format”.

Ejemplo: (Aplicación Windows)Imports System.Drawing.Drawing2DImports System.DrawingPublic Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim G As Graphics = Me.CreateGraphics Dim I As Image = Image.FromFile("C:\Ruta\archivo.jpeg") Dim R As Rectangle = New Rectangle(New Point(40, 40), New Size(300, 300)) Dim F2 As StringFormat = New StringFormat(StringFormatFlags.NoClip) F2.LineAlignment = StringAlignment.Far F2.Alignment = StringAlignment.Far G.DrawImage(I, R) G.DrawString("Texto", Me.Font, Brushes.Red, CType(R, RectangleF), F2) End SubEnd Class

Victor
Agregar 1 formulario y un boton al proyecto.
Victor
Agregar un boton al proyecto.
Victor
Cambiar la ruta del archvivo de la imagén.
Page 46: .Net Framework 2.0 Application Development Foundation.

6.Threading:El concepto básico detrás de threading es desarrollar múltiples operaciones concurrentemente; cada una de estas operaciones puede ser pensada en un hilo independiente de lógica.

•Creando Hilos.Los hilos proveen alto performance en aplicaciones, en el .Net Fw están contenidos en el namespace “System.Threading”

Ejemplo: (Aplicación de consola)Imports System.ThreadingModule Threads Public Delegate Sub Threadstart() Sub Main() Dim operation As New Threadstart(AddressOf simpleWork) For x As Integer = 1 To 5 Dim TheThread As New Thread(AddressOf operation.Invoke) TheThread.Start() Next Console.ReadLine() End Sub Sub SimpleWork() Console.WriteLine("Thread:{0}", Thread.CurrentThread.ManagedThreadId) End SubEnd Module

victor
No identificador asociado a cada hilo.
Page 47: .Net Framework 2.0 Application Development Foundation.

•Usando Thread.JointCuando se desarrollan aplicaciones con hilos, a menudo se hace necesario saber cuando los hilos terminaron su ejecución, para lograr esto la clase “Thread” soporta el método “Join”. Este método le dice a la aplicación que espere hasta que los hilos hayan sido completados, previamente dichos hilos hayan sido agrupados.Ejemplo: (Aplicación de consola)Imports System.ThreadingModule Threads Public Delegate Sub Threadstart() Sub Main() Dim operation As New Threadstart(AddressOf SimpleWork) Dim TheThreads(4) As Thread

For x As Integer = 0 To 4 TheThreads(x) = New Thread(AddressOf operation.Invoke) TheThreads(x).Start() Next For Each t As Thread In TheThreads t.Join() Next Console.ReadLine() End Sub Sub SimpleWork() Thread.Sleep(1000) Console.WriteLine("Thread:{0}", Thread.CurrentThread.ManagedThreadId) End SubEnd Module

victor
Crea, pero no inicia un nuevo hilo.
victor
Empieza el trabajo en un nuevo hilo.
Page 48: .Net Framework 2.0 Application Development Foundation.

•Pasando datos a hilos.En el mundo real se necessita pasaar información a hilos individuales; para hacer esto se necesita usar un nuevo ddelegado llamado “ParameterizedStartThread”, dichos delegados especifican una firma de método con un solo parámetro pasado del tipo “Object” y retornan un valor nothing.

Ejemplo: (Aplicación de consola)Imports System.ThreadingModule Threads Public Delegate Sub ParameterizedThreadStart(ByVal sender As Object) Sub Main() Dim operation As New ParameterizedThreadStart(AddressOf WorkWithParameter) Dim TheThreads As New Thread(AddressOf operation.Invoke) TheThreads.Start("Goodbye") Console.ReadLine() End Sub Sub WorkWithParameter(ByVal o As Object) Dim info As String = CType(o, String) For x As Integer = 0 To 9 Console.WriteLine("Thread:{0}:{1}", info, Thread.CurrentThread.ManagedThreadId) Thread.Sleep(1000) Next End SubEnd Module

Page 49: .Net Framework 2.0 Application Development Foundation.

•Compartiendo datos.Compartir datos entre hilos debe ser una operación cuidadosaa, ya que múltiples hilos podrían interrogar a nuestro objeto (variable) de forma simultánea y alterar su resultado. Para ello .Net Fw adicionó la clase “Interlocked” y sus métodos estáticos.

Ejemplo: (Aplicación de consola)Imports System.ThreadingModule Threads Public Delegate Sub ThreadStart() Public Class Counter Public Shared Count As Integer End Class Sub Main() Dim starter As New ThreadStart(AddressOf UpdateCount) Dim threads() As Thread = New Thread(10) {} For x As Integer = 0 To 9 threads(x) = New Thread(AddressOf starter.Invoke) threads(x).Start() Next

Page 50: .Net Framework 2.0 Application Development Foundation.

For x As Integer = 0 To 9 threads(x).Join() Next Console.WriteLine("Total:{0}", Counter.Count) Console.ReadLine()

End Sub Sub UpdateCount() For x As Integer = 1 To 10000 Interlocked.Increment(Counter.Count) 'Counter.Count = Counter.Count + 1 Next End SubEnd Module

•El modelo de programación asíncrono.A travez del .Net Fw ews posible desarrollar tareas en una forma no lineal usando el Asynchronous Programming Model (APM) de este modo las aplicaciones son más receptivas, corren mejor y el sistema se esta ejecutando en su totalidad.

APM permite ejecutar porciones de código en hilos separados, muchas clases soportan APM mediante los métodos “BeginXXX” y “EndXXX” ejecutándolos asíncronamente.

victor
Interlocked protege que procesadores con Hypertreading incrementen más de lo esperado en la variable.
Page 51: .Net Framework 2.0 Application Development Foundation.

•Rendezvous Model.Existen tres modelos de programación asíncrona con el modelo APM conocidos como: (Wait-Until-Done; Polling; Callback).

a)Wait-Until-Done. Permite iniciar la llamada asincrona y desarrollador otro trabajo, una vez el otro trabajo es hecho, usted puede intentar finalizar la llamada; de modo que este hará un bloqueo hasta que la llamada asíncrona este completada.

Ejemplo: (Aplicación de consola)Imports System.ioModule Threads Public Delegate Sub ThreadStart() Sub Main() Dim Buffer() As Byte = New Byte(30000000) {} Dim filename As String = String.Concat("C:\WINDOWS\Symbols\dll", "\mfc80ud.i386.pdb") Dim strm As FileStream = New FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read, 1024, FileOptions.Asynchronous) Dim result As IAsyncResult = strm.BeginRead(Buffer, 0, Buffer.Length, Nothing, Nothing) Sleep() Dim NumBytes As Integer = strm.EndRead(result) strm.Close() Console.WriteLine("Read {0} bytes", NumBytes) ‘Console.WriteLine(BitConverter.ToString(Buffer)) Console.ReadLine()End Sub

victor
Busco leer un archvo de gran tamaño!
victor
El resultado de una operación asíncrona, es un "IAsyncResult" en lugar de un número de bytes (como sería lo normal para este ejemplo).
victor
Para comprender la llamada asincrona comparamos el método "FileStram.Read" y el método asincrono "FileStream.BeginRead", el primero recive tres parámetros, mientras el método asíncrono recibe cinco donde los dos parámetros adicionales soportarán APM.
victor
Cuando la llamada "BeginRead" es hecha, los valores de "Nothing" son especificadas para el callback y el objeto estado, ya que no vamos a hacer un callback estos son innecesarios; luego "sleep" es hecho u algun trabajo y el código finalmente llama a "EndRead" el cual bloqueará el hilo hasta que la llamada asíncronaa este completada.
Page 52: .Net Framework 2.0 Application Development Foundation.

Sub Sleep() Threading.Thread.Sleep(1000) End SubEnd Module

b)Polling Model. Este método es similar, con la excepción que el código esperará resultados “IAsyncResult” para ver que este completado.

Ejemplo: (Aplicación de consola)Imports System.IoImports System.ThreadingModule Threads

Sub Main() Dim Buffer() As Byte = New Byte(30000000) {} Dim filename As String = String.Concat("C:\WINDOWS\Symbols\dll", "\mfc80ud.i386.pdb") Dim strm As FileStream = New FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read, 1024, FileOptions.Asynchronous) Dim result As IAsyncResult = strm.BeginRead(Buffer, 0, Buffer.Length, Nothing, Nothing) While Not result.IsCompleted Thread.Sleep(100) End While Dim NumBytes As Integer = strm.EndRead(result) strm.Close() Console.WriteLine("Read {0} bytes", NumBytes) 'Console.WriteLine(BitConverter.ToString(Buffer)) Console.ReadLine() End SubEnd Module

victor
Propiedad del "IAsyncResult" retornada por el "BeginRead", se continua trabajando hasta que la operación este completada.
victor
No le paso nada por que no hay retrollamada.
Page 53: .Net Framework 2.0 Application Development Foundation.

c) Callback Model. Requiere que especifiquemos un método de retrollamada e incluir cualquier estado que necesitemos en el método de retrollamada para completar la operación. En este modelo creamos un nuevo delegado “AsyncCallback”, especificando un método para llamar (en otro hilo) para completar la operación, en adición estamos especificando (opcionalmente) algún objeto que podamos necesitar como el estado de la llamada misma.

Ejemplo: (Aplicación de consola)Imports System.IoImports System.ThreadingModule Threads Public Buffer() As Byte = New Byte(30000000) {} Sub Main() TestCallBackAPM() Console.WriteLine("Otro proceso") Console.ReadLine() End Sub Public Sub TestCallBackAPM() Dim filename As String = String.Concat("C:\WINDOWS\Symbols\dll", "\mfc80ud.i386.pdb") Dim strm As FileStream = New FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read,

1024, FileOptions.Asynchronous) Dim result As IAsyncResult = strm.BeginRead(Buffer, 0, Buffer.Length, New AsyncCallback(AddressOf

CompleteRead), strm) End Sub

victor
Tres primeros parámetros normales del método.
victor
Llamada asincrona.
victor
Retrollamada.
victor
Parámetro pasado a la retrollamada que se pasa como un objeto "IAsyncResult".
Page 54: .Net Framework 2.0 Application Development Foundation.

Public Sub CompleteRead(ByVal result As IAsyncResult)

Dim strm As FileStream = CType(result.AsyncState, FileStream) Dim NumBytes As Integer = strm.EndRead(result) strm.Close() Console.WriteLine("Read Completed") Console.WriteLine("Read {0} bytes", NumBytes) End SubEnd Module

•Excepciones & APM.Cuando se está usando APM pueden ocurrir excepciones durante el procesamiento asíncrono, para manejar esto las excepciones en APM ocurren en el método “EndXXX” ya que de lo contrario no sabríamos cómo controlarlas.•Usando el ThreadPool.En capítulos anteriores creamos nuestros propios threads, pero realmente esto no es necesario ya que el .Net Fw incluye un “ThreadPool” que puede ser reutilizado. El método “QueueWorkItem” adiciona una pieza de trabajo al threadpool para ser ejecutado por un thread disponible.

victor
Parametero pasado de la retrollamada.
victor
Debemos convertirlo a su forma original.
Page 55: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.IoImports System.ThreadingModule Threads Public Buffer() As Byte = New Byte(30000000) {} Sub Main() Dim filename As String = String.Concat("C:\WINDOWS\Symbols\dll", "\mfc80ud.i386.pdb") Dim strm As FileStream = New FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read, 1024, FileOptions.Asynchronous) Dim WorkItem As New WaitCallback(AddressOf WorkWithParameter) ThreadPool.QueueUserWorkItem(WorkItem, strm) Console.WriteLine("Otro proceso") Console.ReadLine() End Sub Public Sub WorkWithParameter(ByVal o As Object) Dim strm As FileStream = CType(o, FileStream) Dim result As Integer = strm.read(Buffer, 0, Buffer.Length) Console.WriteLine("Read Completed") Dim NumBytes As Integer = result strm.Close() Console.WriteLine("Read {0} bytes", NumBytes) End SubEnd Module

victor
Método que hará el trabajo en el hilo.
victor
Representa un método de devolución de llamada que se desea ejecutar en un subproceso de "ThreadPool".
victor
Adiciona una pieza de código al ThreadPool para ser ejecutado por cualquier hilo libre.
Page 56: .Net Framework 2.0 Application Development Foundation.

Operating System

Process

6. Application Domain & Services:Los desarrolladores a menudo necesitan correr assemblies de

terceros, sin embargo esto puede permitir el uso ineficiente de recursos y vulnerabilidades de seguridad, la mejor forma para gestionar el riezgo es crear un application domain y llamar el assembly desde dentro del entorno protegido.

• Que es un Application Domain.Es un contenedor lógico que permite correr múltiples assemblies

dentro de un singular proceso. Los application Domain ofrecen muchas de las características de un rpoceso como espacios separados de memoria y acceso a los recursos, sin embargo los AppDomains son más eficientes que los procesos mismos.

.Net Fw Runtime

Application Domain Application Domain

Assembly Assembly Assembly

Page 57: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Ejemplo: (Aplicación de consola)Imports System.IoImports System.ThreadingModule Domains

Sub Main() Dim d As AppDomain = AppDomain.CreateDomain("NewDomain") Console.WriteLine("Host Domain: " + AppDomain.CurrentDomain.FriendlyName) Console.WriteLine("Child Domain: " + d.FriendlyName) Console.ReadLine() End SubEnd Module

•Configurando Aplications Domains.La aplicación más importante en cuanto a modificar la consiguración por defecto para un application Domain es restringir los permisos para reducir el riezgo asociado con las vulnerabilidades.

Para controlar el riezgo se creo la evidencia, que son los permisos asignados al aassembly en el Application Domain, esto es posible mediante el objeto “System.Security.Policy.Zone” y la enumeración “System.Security.SecurityZone”.

Page 58: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.SecurityImports System.Security.PolicyModule Domains

Sub Main() Dim HostEvidence As Object() = {New Zone(SecurityZone.Internet)} Dim internetEvidence As Evidence = New Evidence(HostEvidence, Nothing) Dim MyDomain As AppDomain = AppDomain.CreateDomain("MyDomain") MyDomain.ExecuteAssembly(“Nombre del Assembly", internetEvidence) Console.ReadLine() End SubEnd Module

•Creando Servicios Windows.Crear servicios nos permite correr assemblies en background, sin ninguna interacción del usuario; los servicios son perfectos cuando buscamos monitorear algo, escuchar conexiones de entrada, etc…

•Que es un Servicio Windows.Son procesos que corren en background, sin interfaz de usuario y con sus propias sesiones de usuario; los servicios Windows son ideales para implementar una aplicación que debe correr continuamente y no necesita interactuar con el usuario final.

victor
Debo copiar el ejecutable de otro proyecto a esta carpeta y ejecutarlo.
victor
Puede que al correr el proyecto, salte un error; para lo cual debo cambiar "SecurityZone.Internet" por "SecurityZone.MyComputer". Esto indica que el assembly que estoy cargando requiere de mayores permisos para su ejecución.
Page 59: .Net Framework 2.0 Application Development Foundation.

Los servicios Windows no se pueden depurar directamente (F5) como otras aplicaciones, en lugar de ello se debe instalar y atar el debuguer a un determinado servicio de proceso.

Ejemplo: (Servicio Windows)a.Crear el servicio windows y llamarlo “MonitorWebSite”b.En el “ServiceDesignerView”, hacer click derecho y cambiar las propiedades “Name” & “ServiceName” a MonitorWebSite. Luego establecer “CanPauseAndClontinue” & “CanShutDown” estas propiedades a True.c.En la ventana de código MonitorWebSite agregamos:

Imports System.TimersImports System.IOImports System.NetPublic Class MonitorWebSite Private t As Timer = Nothing

Protected Overrides Sub OnStart(ByVal args() As String) t.Start() End Sub Protected Overrides Sub OnStop() t.Stop() End Sub Protected Overrides Sub OnContinue() t.Start() End Sub Protected Overrides Sub OnPause() t.Stop() End Sub Protected Overrides Sub OnShutdown() t.Stop() End Sub

Page 60: .Net Framework 2.0 Application Development Foundation.

Public Sub New() ' Llamada necesaria para el Diseñador de Windows Forms. InitializeComponent() t = New Timer(10000) AddHandler t.Elapsed, New System.Timers.ElapsedEventHandler(AddressOf Me.t_Elapsed) End Sub Protected Sub t_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs) Try Dim url As String = "http:www.microsoft.com" Dim g As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest) Dim r As HttpWebResponse = CType(g.GetResponse, HttpWebResponse) Dim path As String = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "log.txt" Dim tw As TextWriter = New StreamWriter(path, True) tw.WriteLine(DateTime.Now.ToString + "for " + url + ": " + r.StatusCode.ToString) tw.Close() Catch ex As Exception System.Diagnostics.EventLog.WriteEntry("Application", "Exception: " + ex.Message.ToString) End Try End SubEnd Class

d. Compilar “MonitorWebSite”e. Adicionar un instalador al proyecto, esto se hace en la vista de diseño de la clase, hacer click derecho y

seleccionar “Agregar Instalador”-> esto crea dos objetos (ServiceProcessInstalller1 y ServiceInstaller1).f. En “ServiceInstaler” colocar las propiedades:

-Startype=Automatic-Description=Logs responses from Microsoft.com-DisplayName=Web Site Monitor

En ServiceProcessInstaller1 colocar la porpiedad:-Account=LocalSystem

Page 61: .Net Framework 2.0 Application Development Foundation.

g. Agregar un nuevo proyecto a la solución y seleccionar “otros tipos de proyecto”->”Proyecto de instalación”h. En la ventana “Explorador de soluciones” hacer click derecho sobre el proyecto de instalación y seleccionar

“Agregar”->”Resultados del proyecto”, en la ventana que aparece seleccionar: y “Aceptar”-Proyecto->”MonitorWebSite”-ResultadoPrincipal

i. Adicionar una “Custom Action” para instalar el ejecutable del servicio mediante los pasos:-Sobre el proyecto de instalación, hacer click derecho y seleccionar ver->”Acciones personalizadas”-Aparecerá una ventana “Seleccionar elemento en el proyecto” y sseleccionar “Carpeta de la aplicación”-

>”Resultado principal de monitorwebsite”-Botón derecho en el proyecto de instalación y click en “generar”, lo cual creará el exe.

j. Click derecho en el “Proyecto de instalación” y ya se puede instalar el servicio y controlar su “inicio/Fin” de ejecución mediante la consola de administración.

9.Application Domain & Services:Este capítulo cubre los tópicos de instalar y configurar aplicaciones;

permitir a las aplicaciones ser parametrizables a la hora de su instalación brindará un mejor impacto sobre los clientes finales.

• Configurando Settings:Colocar los settings de configuración en un archivo permite a los

desarrolladores modelar las configuraciones en una forma orientada a objetos y sin tener que depender del registro principal de windows, elevando su nivel de compatibilidad.

victor
Al correr el servicio veremos que en donde se instaló se creará un log.txt que provará cada 10 segundos el request del sitio de mcrosoft.
Page 62: .Net Framework 2.0 Application Development Foundation.

La librería que sirve de repositorio para todas las configuraciones es “System.Configuration”, de las cual se desprenden las clases Configuration y Configuration.Manager.

•Configurando Settings:Colocar los settings de configuración en un archivo permite a los desarrolladores modelar las configuraciones en una forma orientada a objetos y sin tener que depender del registro principal de windows, elevando el nivel de compatibilidad.

Ejemplo: (Aplicación de consola)<?xml version="1.0" encoding="utf-8" ?><configuration>

<appSettings><add key="AppKey" value="Hello World!"/>

</appSettings><connectionStrings>

<clear/><add name="AdventureWorkString" providerName="System.Data.SqlClient"

connectionString="Data Source=localhost;Initial Catalog=AdventureWorkss;Integrated Security=True"/> </connectionStrings>

<!—Continua segmento autogenerado por el Vs--></configuration>

Page 63: .Net Framework 2.0 Application Development Foundation.

Imports System.ConfigurationImports System.Collections.SpecializedImports System.TextModule ConfiguracionSub Main() Dim AllAppSettings As NameValueCollection = ConfigurationManager.AppSettings Dim SettingsEnumerator As IEnumerator = AllAppSettings.Keys.GetEnumerator Dim counter As Int32 Console.WriteLine("Segmento AppSettings") While SettingsEnumerator.MoveNext Console.WriteLine("Item {0} value {1}", AllAppSettings.Keys(counter), AllAppSettings(counter)) counter = counter + 1 End While

Console.WriteLine("Segmento connectionStrings") Dim MySettings As ConnectionStringSettingsCollection = ConfigurationManager.ConnectionStrings For Each individualSettings As ConnectionStringSettings In MySettings Dim sb As New StringBuilder sb.Append("Full Connection string: " + individualSettings.ConnectionString) sb.Append("Provider Name: " + individualSettings.ProviderName) sb.Append("section Name: " + individualSettings.Name) Console.WriteLine(sb.ToString) Next Console.ReadLine() End SubEnd Module

Page 64: .Net Framework 2.0 Application Development Foundation.

•Usando el .Net Fw Configuration Tool:El .Net Fw Configuration tool es una herramienta que habilita a los desarrolladores para gestionar cualquier aspecto de configuración con un assembly; fundamentalmente tres son las tareas que permite esta herramienta:

-Configurar y gestionar assemblies en el GAC-Ajustar las polizas de seguridad en el acceso al código-Ajustar servicios remotos

La herramienta se encuentra disponible en:

Panel de Control->Herramientas Administrativas->Configuración de Microsoft .Net Fw

10.InstrumentaciónLa instrumentación consiste en medir que pasa en la aplicación, no importa lo bien que se encuentre escrita siempre existirán condiciones ajenas (como la ram, errores de hardware, etc…) que la aplicación pueda encontrar y en donde se presenten comportamientos inesperados. Mediante el Event Log (visor de sucesos) los desarrolladores pueden guardar aspectos del estado de una aplicación.

Page 65: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.ConfigurationImports System.Collections.SpecializedImports System.TextModule Instrumentacion

Sub Main() CreateEventLog() Console.ReadLine() End Sub Public Sub CreateEventLog() Dim DemoLog As New EventLog("Capitulo10") DemoLog.Source = "Capitulo10" DemoLog.WriteEntry("Descripción del Log.", EventLogEntryType.Information) End SubEnd Module

Nota: También es posible escribir al log de eventos predefinidos del sistema (System, Security ó Application) lo que debemos hacer es indicarle al constructor los eventos del sistema:

Dim Demolog as New EventLog(“Predefinido”)

También es posible borrar todos los eventos de un aplicativo (eliminar un determinado Log de eventos) para lo cual escribimos:

EventLog.Delete(“Nombre del Log”)

victor
Nombre del Log de eventos.
Page 66: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Module Instrumentacion Sub Main() CreateEventLog() ClearEventLog() ‘DeleteEventLog() Console.ReadLine() End Sub Public Sub CreateEventLog() Dim DemoLog As New EventLog("Capitulo10") DemoLog.Source = "Capitulo10" DemoLog.WriteEntry("Descripción del Log.", EventLogEntryType.Information) End Sub Public Sub ClearEventLog() Dim DemoLog As New EventLog("Capitulo10") DemoLog.Source = ("Capitulo10") DemoLog.Clear() End Sub Public Sub DeleteEventLog() EventLog.Delete("Capitulo10") End SubEnd Module

•Monitoreando el Performance.La definición de un proceso es un segmento de memoria que contiene recursos, dicho en otros palabras es una tarea aislada desarrollada por el sistema operativo; por consiguiente un proceso pertenece a uno o más hilos del sistema operativo.

Page 67: .Net Framework 2.0 Application Development Foundation.

Existen cuatro métodos para identificar procesos:-GetCurrentProcess-GetProcessbyId-GetProcessbyName-GetProcess

Ejemplo: (Aplicación de consola)Module Instrumentacion Sub Main() Dim ThisProcess As Process = Process.GetCurrentProcess Console.WriteLine("Current Process ID:{0}", ThisProcess.Id) Try Dim SpecificProcess As Process = Process.GetProcessById(ThisProcess.Id) Console.WriteLine("Current Process Name:{0}", SpecificProcess.ProcessName) Catch Problem As ArgumentException Console.WriteLine(Problem.Message) End Try Console.ReadLine() End SubEnd Module

És posible conocer todos y cada uno de los procesos que estan corriendo en una maquina, mediante el método “GetProcess” acompañado por el nombre (identificador) de la maquina.

Page 68: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Module Instrumentacion Sub Main() GetAllProcess() Console.ReadLine() End Sub Public Sub GetAllProcess() Try Dim AllProcess() As Process = Process.GetProcesses("victorbustos") For Each current As Process In AllProcess Console.WriteLine(current.ProcessName) Next Catch Problem As ArgumentException Console.WriteLine(Problem.Message) End Try End SubEnd Module

11.InteroperaciónLa interacción es un nombre genérico usado para referirse al proceso de interactuar con código no-gestionado desde dentro del código gestionado; el proceso de interacción se hace necesario debido a:

-Muchas compañías tienen una larga cantidad de código legado, código que fue costoso en su momento y de una u otra forma ya ha sido probado.

Page 69: .Net Framework 2.0 Application Development Foundation.

-No todas las API’s han sido adoptadas por el .Net Fw, de modo que algunas tareas sólo son posibles si se usa la interacción.

Antes de la llegada del .Net Fw, COM fue el Fw principal para que los desarrolladores interactuaran con el sistema operativo windows; ya sea .Net ó COM siempre se ha acude a librerías externas (que una vez importadas) pueden ser consumidas para una determinada funcionalidad específica.

•Importando Librerías de Tipo.El .Net Fw provee amplio soporte para la interoperabilidad con COM, el mecanismo que sirve como proxy para que el .Net pueda comunicarse con COM es conocido como Runtime Callable Wraper (RCW) el cual permite el intercambio de tipos de datos, manejo de eventos y manejo de interfaces.

A diferencia de los componentes .Net, los componentes COM deben ser registrados mediante “Regsvr32.exe” antes de que estos puedan ser usados, la utilización de ellos es posible mediante:

Page 70: .Net Framework 2.0 Application Development Foundation.

-Type Library Importer tool (tlblmp.exe)-Visual Studio -> boton derecho sobre el Proyecto->Agregar Referencia

Nota: Cuando se utiliza la línea de comandos (tlbimp.exe), este crea un nuevo ensamblado .Net; partiendo del componente COM que luego es posible agregar directamente al proyecto.

Herramientas Usadas por COM Interop

Nombre Descripción Aplicación

Type Library Importer Importa un nuevo assembly .Net basado en el componente COM

TlbImp.exe

Type Library Exporter Crea una librería de tipos COM que puede ser consumida por una aplicación .Net

TlbExp.exe

Registry Editor Todos los componentes COM deben tener una entrada en el registro de windows. El editor del registro permite buscar y gestionar las entradas.

Regedit.exe

Intermediate Language Disasssembler

Esta herramienta permite ver una representación visual del Intermediate Language.

Ildasm.exe

Assembly Registration Tool Habilita agregar y remover assemblies .Net de la base de datos de registros.

Regasm.exe

Page 71: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Fragmento de Código)1-Crear una aplicación windows2-Agregar una referencia COM del objeto (Adobe Acrobat 8)3-Arrastrar el control desde el cuadro de herramientas4-Agregar las siguientes líneas de código, en el page load del formulario:

-AxAcroPdf1.loadFile(“C:\\sample.pdf”)-AxAcroPdf1.Print

•Exponiendo componentes .Net a COM.Ya que los componentes COM pueden ser consumidos por el .Net, el proceso inverso también es posible mediante un proxy llamado COM Callable Wrapper(CCW) que maneja el intercambio de items entre .Net y COM.

Ejemplo: (Fragmento de Código)1-Crear una biblioteca de clases2-Agregar las clases que se desean consumir3-Hacer click derecho sobre el explorador de soluciones, en propiedades4-En propiedades seleccionar el item “compilar” y chequear el item-> “registrar para la interoperabilidad con COM”

Mientras un assembly puede ser visible a COM la documentación MSDN provee los siguientes consejos para asegurar que las cosas marchen bien según lo planeado:

-Todas las clases deben usar el contructor por defecto-Cualquier tipo que sea expuesto debe ser público

Page 72: .Net Framework 2.0 Application Development Foundation.

-Cualquier miembro que sea expuesto debe ser público-Las clases abstractas no son hábiles para ser consumidas

Ejemplo: (Biblioteca de Clases)1-Crear un proyecto biblioteca de clases2-Agregar la siguiente clase:

<ComVisible(False)> _Public Class ComVisiblePerson Private _firstName As String Private _lastName As String Private _salary As String <ComVisible(True)> _ Public Property FirstName() As String Get Return Me._firstName End Get Set(ByVal value As String) Me._firstName = value End Set End Property <ComVisible(True)> _ Public Property LastName() As String Get Return Me._lastName End Get Set(ByVal value As String) Me._lastName = value End Set End Property

Page 73: .Net Framework 2.0 Application Development Foundation.

<ComVisible(False)> _ Public Property Salary() As Int32 Get Return Me._salary End Get Set(ByVal value As Int32) Me._salary = value End Set End PropertyEnd Class

3-Compilar la Dll a MSIL:vbc /t:library comvisibleperson.vb

4-Ejecutar el type library exporter:tlbexp comvisibleperson.dll /out:comvisiblepersonlib.tlb

5-Crear un script de recursos (comvisibleperson.res) con la siguiente interface definition language: IDR_TYPELIB1 typelib "ComVisiblePersonlib.tlb“

6-Recompilar la librería con el nuevo archivo de recursos:vbc /t:library comvisibleperson.vb /resource:comvisibleperson.res

El resultado será una nueva Dll .Net que es compatible con las aplicaciones COM

Page 74: .Net Framework 2.0 Application Development Foundation.

12. Reflection.El código en el CLR es empaquetado en un assembly, estos

metadatos son la información que el CLR usa para cargar y ejecutar código; esto incluye información de tipo para todas las clases, estructuras, delegados e interfaces en el assembly.

Un assembly es un contenedor lógico para las diferentes partes de datos que el CLR necesita ejecutar, estas partes incluyen:

-Assembly Metadata: Incluye datos que son definidos en el assmbly como el nombre, la versión, el strong name e información de cultura. Al assembly metadata también se le llama el manifiesto.

Fig No 2. Estructura de un Assembly

Type Metadata

Assembly Metadata

Code (IL)

Resourses

Page 75: .Net Framework 2.0 Application Development Foundation.

-Type Metadata: Es toda la información que describe cómo luce un tipo, los miembros individuales de un tipo (cómo los métodos, las propiedades y sus constructores)-El código es el IL que es compilado a código de maquina cuando el assembly es compilado.-Los recursos son objetos que son strings, imágenes ó archivos que son usados desde el código.

Ejemplo: (Aplicación de consola)Imports System.ReflectionModule Reflection Sub Main() Dim path As String = "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\system.dll" Dim a As Assembly = Assembly.LoadFile(path) ShowAssemblyInfo(a) Dim ourAssembly As Assembly = Assembly.GetExecutingAssembly ShowAssemblyInfo(ourAssembly) Console.ReadLine() End Sub Public Sub ShowAssemblyInfo(ByVal a As Assembly) Console.WriteLine(a.FullName) Console.WriteLine("From GAC? {0}", a.GlobalAssemblyCache) Console.WriteLine("Path: {0}", a.Location) Console.WriteLine("version: {0}", a.ImageRuntimeVersion)

victor
Indica si el assembly fue cargado del GAC.
victor
Consigue el path del assembly.
victor
Versión del assembly.
victor
Al correr el proyecto, no solo se muestra como un tipo que corro dentro de la aplicación, también se muestran otros tipos como (MyApplication, MyComputer, etc..)Para comprobar el IL podemos abrir la aplicación "Ildasm.exe" que se encuentra en la carpeta del VS. Luego abrimos el exe que genero nuestra aplicación y observamos los typos de forma gráfica.
Page 76: .Net Framework 2.0 Application Development Foundation.

For Each m As [Module] In a.GetModules Console.WriteLine("Modulo: {0}", m.Name) For Each t As Type In a.GetTypes Console.WriteLine("Tipos: {0}", t.Name)

Next Next Console.WriteLine() End SubEnd Module

•Assembly Attributes.Existen muchas piezas de información de un assembly que no son expuestos directamente al usuario, estas piezas de información son los atributos de los assemblies y la más característica de ellas son (el copyright, información de la compañía, información cultural y la versión del ensamblado).

La forma de llamar dichos atributos es mediante el método “GetCustomAttributes” que hace parte de la interface “IcustomAttributeProvider” usada para buscar tipos de objetos que proveen atributos parametrizables.

Page 77: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.ReflectionModule Reflection Sub Main() Dim a As Assembly = Assembly.GetExecutingAssembly Dim attrs As Object = a.GetCustomAttributes(True) For Each attr As Attribute In attrs Select Case attr.GetType.Name Case GetType(AssemblyTitleAttribute).Name Console.WriteLine("Assembly Título:{0}:", CType(attr, AssemblyTitleAttribute).Title) Case GetType(AssemblyCompanyAttribute).Name Console.WriteLine("Assembly Compañia:{0}:", CType(attr, AssemblyCompanyAttribute).Company) Case GetType(AssemblyFileVersionAttribute).Name Console.WriteLine("Assembly Versión: {0}:", CType(attr, AssemblyFileVersionAttribute).Version) End Select Next Console.ReadLine() End SubEnd Module

->Nota: Hacemos click en el proyecto y le damos mostrar todos los archivos; en el archivo “AssemblyInfo.vb” agregamos el siguiente código:

<Assembly: AssemblyTitle("AssemblyDemo")> <Assembly: AssemblyCompany("Compañia Pepito, Inc.")> <Assembly: AssemblyFileVersion("1.2.0.0")>

Page 78: .Net Framework 2.0 Application Development Foundation.

•Reflejando Typos.Para conseguir los miembros de un tipo, primero se debe entender cómo obtener los objetos que componen un tipo ya que esto es posible en un No de formas:

-Desde una clase assembly-Desde una clase módulo-Desde instancias de un objeto-Usando la palabra clave GetTypes

La clase “Type” representa un tipo singular, permitiendo observar los métodos , propiedades, eventos, interfaces y su herencia del sistema. Una vez se ha conseguido la instancia del tipo objeto, se puede obtener información descriptiva como (el Nombre, el NameSpace si es un valueType, si es abstracto, si es público u si el tipo se refiere a una clase).

Conseguir el acceso a los (métodos, propiedades, campos y eventos) de una determinado tipo en reflection es posible mediantes las clases que finalizan con el sufijo “Info” (PropertyInfo, EventInfo, MethodInfo, etc..) y que a su vez son derivadas de una clase más abstracta llamada “MemberInfo”.

Page 79: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.ReflectionModule Reflection Sub Main() Dim t As Type = GetType(Reflection) For Each NestedType As Type In t.GetNestedTypes Console.WriteLine("Typo anidado:{0}", NestedType.Name) For Each prop As PropertyInfo In NestedType.GetProperties Console.WriteLine("Propiedad: {0}", prop.Name) Next For Each ev As EventInfo In NestedType.GetEvents Console.WriteLine("Evento: {0}", ev.Name) Next For Each mt As MethodInfo In NestedType.GetMethods Console.WriteLine("Método: {0}", mt.Name) Next Next Console.ReadLine() End Sub

Public Class Claseanidada Public Property PropiedadX() Get End Get Set(ByVal value) End Set End Property Public Event EventoX() Public Sub ProcedimientoX() End Sub End ClassEnd Module

Page 80: .Net Framework 2.0 Application Development Foundation.

13. Mail.El email es el mecanismo de comunicación más popular que nos

permite enviar archivos, reportes ó notificar a usuarios de problemas u eventos. El .Net Fw provee el namespace System.Net.Mail el cual provee clases que nos habilitan la fácil creación y transmisión de mensajes, los mensajes pueden incluir texto plano, HTML u attachments.

• Crear un Email:Crear un email es una tarea simple que contiene elementos como

(sender, recipient, subject & body) ú llegar a ser algo más complejo que implica múltiples vistas (texto plano, Html) attachmens u imágenes.

Ejemplo: (Aplicación de consola)

1-Agregar un archivo de configuración “app.config” y especificar la siguiente configuración:<?xml version="1.0" encoding="utf-8" ?><configuration> <system.net> <mailSettings> <smtp> <network host="smtpout.secureserver.net" port="25" userName="[email protected]"

password="XXXXXX"/> </smtp> </mailSettings>

…. Resto del archivo de configuración que viene por defecto.

Page 81: .Net Framework 2.0 Application Development Foundation.

2-Agregar un módulo con el siguiente código:Imports System.Net.MailImports System.Net.MimeImports System.IOModule Mail Sub main() Dim htmlBody As String = "<html><body><h1>Imagen</h1><br><img src="" Cid:Pic1""></body></html>" Dim avHtml As AlternateView = AlternateView.CreateAlternateViewFromString(htmlBody, Nothing, MediaTypeNames.Text.Html) Dim pic1 As LinkedResource = New LinkedResource("c:\archivo.tpg", MediaTypeNames.Image.Jpeg) pic1.ContentId = "Pic1" avHtml.LinkedResources.Add(pic1) Dim textbody As String = "Debes usar un clinete email que soporte mensajes html" Dim avText As AlternateView = AlternateView.CreateAlternateViewFromString(textbody, Nothing, MediaTypeNames.Text.Plain) Dim m As MailMessage = New MailMessage m.AlternateViews.Add(avHtml) m.AlternateViews.Add(avText) m.Attachments.Add(new Attachment("c:\archivo.txt") m.From = New MailAddress("[email protected]", "Pedro Perez") m.To.Add(new MailAddress("[email protected]","Victor Bustos") m.Subject = "una imagen usando vistas alternas" Dim client As SmtpClient = New SmtpClient client.Send(m)

End Sub

End Module

victor
Vista en formato HTML.
victor
Vista en formato de texto plano.
victor
Al crear el cliente se leen las credenciales del archivo de configuración.
Page 82: .Net Framework 2.0 Application Development Foundation.

14. Globalización.El .Net Fw tiene un increíble set de herramientas que pueden ser

usadas para crear aplicaciones que corren en regiones geográficas dispersas. Una aplicación puede ser escrita para que funcione igualmente en japón como en Gran Bretaña, sin virtualmente cambios necesarios en el código. Todo es posible mediante el namespace System.Globalization.

• Usando información cultural:Una de las herramientas núcleo para manipular y retornar

información sobre el contexto cultural de una aplicación se encuentra en la clase “CultureInfo”. Esta clase provee información de cultura específica como el formato de los números y las fechas; hablando más ampliamente abarca el nombre de la cultura, el sistema de escritura, el calendario, el lenguaje y sub-lenguajes, el país y la región proviendo métodos para manipular todos estos aspectos.

Como regla la cultura será agrupada en una de tres categorías (cultura invariante, cultura neutral y cultura específica).

a) Cultura invariante: Significa insensible a la cultura y no necesariamente es la cultura inglesa, pero si tienen elementos asociados que permiten realizar comparaciones.

Page 83: .Net Framework 2.0 Application Development Foundation.

b) Cultura Neutral: Ingles, Francés y Español son culturas neutrales, lo cual significa que esta asociado al lenguaje pero no tiene relaciones específicas a países ó regiones.

c) Culturas Específicas: Es la más precisa de las tres categorías y es representada por una cultura neutral un guión y a continuación una cultura específica.

Ejemplo: (Aplicación de consola)Imports System.GlobalizationImports System.ThreadingModule Globalization Sub main() Dim UsersCulture As CultureInfo = Thread.CurrentThread.CurrentCulture Console.WriteLine("El nombre de esta cultura es: " + UsersCulture.DisplayName) Console.WriteLine("El nombre nativo de esta cultura es: " + UsersCulture.DisplayName) Console.WriteLine("La abreviación ISO de esta cultura es: " + UsersCulture.TwoLetterISOLanguageName) Console.ReadLine() End SubEnd Module

Establecer la información cultural es similar a leerla. “CurrentCulture” es una propiedad de “CurrentThread” que a su vez es una propiedad de la clase “Thread”; por consiguiente es muy fácil establecerla.

Page 84: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.GlobalizationImports System.ThreadingModule Globalization Sub main() Dim UsersCulture As CultureInfo = Thread.CurrentThread.CurrentCulture Console.WriteLine("La actual cultura de esta aplicación es: " + UsersCulture.Name) Thread.CurrentThread.CurrentCulture = New CultureInfo("es-Ve") Console.WriteLine("La nueva cultura de esta aplicación es: " + Thread.CurrentThread.CurrentCulture.Name) Console.ReadLine() End SubEnd Module

Mientras la clase “CultureInfo” provee bastante información detallada sobre una cultura dada, información más granular es a veces necesaria. Para ello la clase “RegionInfo” es un mecanismo para proveer información detallada sobre un país ó región.

“CultureInfo” tiene dos tipos de propiedad que permiten trabajar en conjunción con “RegionInfo” como lo son: Identificador nominal (propiedad name) y los identificadores numéricos (propiedad LCID).

Page 85: .Net Framework 2.0 Application Development Foundation.

Ejemplo: (Aplicación de consola)Imports System.GlobalizationImports System.ThreadingModule Globalization Sub main() Dim UsersCulture As CultureInfo = Thread.CurrentThread.CurrentCulture Dim DemoRegion As RegionInfo = New RegionInfo(UsersCulture.LCID) Console.WriteLine("English Name: " + DemoRegion.EnglishName) Console.WriteLine("ISO Symbol: " + DemoRegion.ThreeLetterISORegionName) Console.WriteLine("Sistema Métrico: " + DemoRegion.IsMetric.ToString) Console.WriteLine("Current Symbol: " + DemoRegion.CurrencySymbol) Console.ReadLine() End SubEnd Module

Una importante razón para usar la clase “CultureInfo” es realizar comparaciones de strings; para ello CultureInfo provee la propiedad “CompareInfo” que a su vez proporciona el método “Compare” para realizar operaciones acompañado de la enumeración “CompareOptions”.

Ejemplo: (Aplicación de consola)Imports System.GlobalizationImports System.ThreadingModule Globalization Sub main() Dim FirstString = "Cafe" Dim SecondString = "cafe" Dim DemoInfo As CompareInfo = New CultureInfo("es-CO").CompareInfo Console.WriteLine(DemoInfo.Compare(FirstString, SecondString, CompareOptions.IgnoreCase)) Console.ReadLine() End SubEnd Module

Page 86: .Net Framework 2.0 Application Development Foundation.

Connotaciones:.Net FW Referido a .Net FrameWork

CLR Common Language Runtime

MSIL Microsoft Intermediate Language

VS Referido a Visual Studio

VB Referido a Visual Basic

USA Estados Unidos de América

ASCII American Stantard Code For Information Interchange

ANSI American National Standards Institute

FIFO First-In, First-Out

SOAP Simple Object Access Protocol

XML Extensible Markup Language

Page 87: .Net Framework 2.0 Application Development Foundation.

Connotaciones:APM Asynchronous Programming Model

GAC Global Assembly Cache

API Application Programming Interface

COM Component Object Model