.Net Framework 2.0
Application Development
Foundation
Contenido:
1.
2.
3.
4.
5.
6.
7.
8.
Framework Fundamentals
Input/Output (I/O)
Searching, Modifying, and Encoding Text
Collections and Generics
Serialization
Graphics
Threading
Application Domains and Services
Que es el .Net Framework
Contenido:
9. Installing and Configuring Applications
10.Instrumentation
11.Application Security
12.User and Data Security
13.Interoperation
14.Reflection
15.Mail
16.Globalization
Que es el .Net Framework
1.
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.
(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 Sub
End 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.
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 Structure
End 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:
•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 Enum
End Module
•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 Structure
End Module
•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 Property
End Class
Interfaces. Tambien conocidas como los contratos, definen un set de
miembros comunes para todas las clases que la interface debe proveer.
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
•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
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 Sub
End 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.
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.
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 Sub
End 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).
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)
Ejemplo: (Aplicación consola)
Imports System.IO
Module 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 Sub
End 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)
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.IO
Module 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 Sub
End 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.IO
Module 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 Sub
End 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.IO
Module 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 Sub
End Module
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.IO
Module 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 Sub
End 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.
Ejemplo (Aplicación de consola)
Imports System.IO
Module 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 Sub
End 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.
Ejemplo (Aplicación de consola)
Imports System.IO
Imports System.IO.Compression
Module 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
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 Using
End Sub
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 Sub
End 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.
•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.RegularExpressions
Namespace 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 Class
End 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.
Ejemplo: (Aplicación de consola)
Imports System.Text.RegularExpressions
Class 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 Sub
End 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.RegularExpressions
Namespace 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 Class
End Namespace
•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.
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
Ejemplo: (Aplicación de consola)
Imports System.Text
Imports System.IO
Module 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 Sub
End 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”
Tipos de Collecciones:
Colecciones
Colecciones
ArrayList
DictionaryBase & DictionaryEntry
Collection Interface
Comparer
Iterators
Queue
HashTable
SortedList
Collectionbase & ReadOnlyCollectionBase
BitArray
Stack
Gestionar datos usando colecciones especializadas es mediante el
namespace “System.Collection.Specialized”
Colecciones Especializadas
Specialized String
Specialized Dictionary
NameValueCollection
CollectionUtil
BitVector32 structure & BitVector32.section
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”:
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
•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.
Ejemplo: (Aplicación de consola)
Imports System.Text
Imports System.IO
Module 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 Sub
End Module
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.Text
Imports System.IO
Module 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 Sub
End 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.
Ejemplo: (Aplicación de consola)
Imports System.Text
Imports System.IO
Module 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 Sub
End 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.
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.Text
Imports System.IO
Module 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 Sub
End 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”.
Ejemplo: (Aplicación de consola)
Imports System.Text
Imports System.IO
Module 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 Sub
End 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).
Ejemplo: (Aplicación de consola)
Imports System.Text
Imports System.IO
Module 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 Sub
End 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..)
Ejemplo: (Aplicación de consola)
Imports System.Text
Imports System.IO
Module 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 Sub
End 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.
Ejemplo: (Aplicación de consola)
Imports System.Text
Imports System.IO
Module 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 Sub
End 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.
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 Region
End Class
Option Explicit On
Option Strict On
Imports System.IO
Imports System.Collections
Module 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 Sub
End Module
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.IO
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
Module 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()
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 Sub
End 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.
Ejemplo: (Aplicación de consola)
Imports System.IO
Imports System.xml.Serialization
Module 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 Sub
End 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”.
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.Drawing
Public 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 Sub
End Class
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.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Imaging
Public 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 Sub
End 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..
Ejemplo: (Aplicación Windows)
Imports System.Drawing.Drawing2D
Imports System.Drawing
Public 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 Sub
End 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.Drawing2D
Imports System.Drawing
Public 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 Sub
End Class
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.Threading
Module 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 Sub
End Module
•Usando Thread.Joint
Cuando 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.Threading
Module 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 Sub
End Module
•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.Threading
Module 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 Sub
End Module
•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.Threading
Module 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
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 Sub
End 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.
•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.io
Module 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
Sub Sleep()
Threading.Thread.Sleep(1000)
End Sub
End 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.Io
Imports System.Threading
Module 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 Sub
End Module
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.Io
Imports System.Threading
Module 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
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 Sub
End 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.
Ejemplo: (Aplicación de consola)
Imports System.Io
Imports System.Threading
Module 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 Sub
End Module
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.
Operating System
Process
.Net Fw Runtime
Application Domain
Assembly
Assembly
Application Domain
Assembly
Ejemplo: (Aplicación de consola)
Imports System.Io
Imports System.Threading
Module 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 Sub
End 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”.
Ejemplo: (Aplicación de consola)
Imports System.Security
Imports System.Security.Policy
Module 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 Sub
End 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.
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.Timers
Imports System.IO
Imports System.Net
Public Class MonitorWebSite
Private t As Timer = Nothing
Protected Overrides
t.Start()
End Sub
Protected Overrides
t.Stop()
End Sub
Protected Overrides
t.Start()
End Sub
Protected Overrides
t.Stop()
End Sub
Protected Overrides
t.Stop()
End Sub
Sub OnStart(ByVal args() As String)
Sub OnStop()
Sub OnContinue()
Sub OnPause()
Sub OnShutdown()
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 Sub
End 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
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.
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>
Imports System.Configuration
Imports System.Collections.Specialized
Imports System.Text
Module Configuracion
Sub 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 Sub
End Module
•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ón
La 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.
Ejemplo: (Aplicación de consola)
Imports System.Configuration
Imports System.Collections.Specialized
Imports System.Text
Module 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 Sub
End 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”)
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 Sub
End 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.
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 Sub
End 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.
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 Sub
End Module
11.Interoperación
La 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.
-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:
-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
Ejemplo: (Fragmento de Código)
1-Crear una aplicación windows
2-Agregar una referencia COM del objeto (Adobe Acrobat 8)
3-Arrastrar el control desde el cuadro de herramientas
4-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 clases
2-Agregar las clases que se desean consumir
3-Hacer click derecho sobre el explorador de soluciones, en propiedades
4-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
-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 clases
2-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
<ComVisible(False)> _
Public Property Salary() As Int32
Get
Return Me._salary
End Get
Set(ByVal value As Int32)
Me._salary = value
End Set
End Property
End 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
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.
Assembly
Metadata
Type
Metadata
Code (IL)
Resourses
Fig No 2. Estructura de un 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.
-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.Reflection
Module 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)
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 Sub
End 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.
Ejemplo: (Aplicación de consola)
Imports System.Reflection
Module 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 Sub
End 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")>
•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”.
Ejemplo: (Aplicación de consola)
Imports System.Reflection
Module 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 Class
End Module
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.
2-Agregar un módulo con el siguiente código:
Imports System.Net.Mail
Imports System.Net.Mime
Imports System.IO
Module 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
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.
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.Globalization
Imports System.Threading
Module 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 Sub
End 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.
Ejemplo: (Aplicación de consola)
Imports System.Globalization
Imports System.Threading
Module 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 Sub
End 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).
Ejemplo: (Aplicación de consola)
Imports System.Globalization
Imports System.Threading
Module 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 Sub
End 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.Globalization
Imports System.Threading
Module 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 Sub
End Module
Connotaciones:
.Net FWReferido 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
Connotaciones:
APM
Asynchronous Programming Model
GAC
Global Assembly Cache
API
Application Programming Interface
COM
Component Object Model
Descargar

.Net Framework 2.0