Vous êtes sur la page 1sur 54

ndice 1. NET: Conceptos Assembly, estructura, jerarquias 2. C# 2.1 Permisos y acceso a atributos 2.2 Herencia 2.3 Polimorfismo 3.

ASP 3.1 Conceptos 3.2 ASP vs ASP.N ! 3.3 Componentes 3.3.1 "ri#$ie%s 3.3.2 &ata'ri#s 3.3.3 (epeater 3.3.) Componentes varios 3.) *inq 3.+ $ie%State 3., $ariables #e session 3.- Paso #e par.metros 3./ 0peraciones Pa'e1 Pa'e2loa#, Pa'e init, etc. 3.3 Controles #e usuarios 3.14 56uery 4. Proyectos Web structuras y componentes "lobal.asa7 8eb.confi' 5. Tecnolo i!s 5.1 "!t!#!se Access $ %&'s +.1.2 A&0.N ! +.1.3 NHibernate +.1.) ntity 9rame%or:s 5.2 Windo(s Co))*nic!tion +o*nd!tion ,WC+5.3 .nternet .n/or)!tion Ser0ices ,..S5.4 Testin +.).1 Testin 1nit!rio ;nit && <S !est .nte r!cion contin*! 5en:ins Automati=aci>n Selenium

Conceptos ener!l .NET


.ntrod*ccion Hace a?os atr.s, cuan#o nosotros #eseabamos tener un pro'rama que se pu#iera ejecutar, era necesario compilarlo. Ca#a uno #e los len'uajes tenia su propio compila#or. No era sencillo po#er compartir c>#i'o #e C@@ con c>#i'o #e $isual Aasic, Babia que buscar un punto #e comunicaci>n entre estos. Para po#er compartir c>#i'o entre los len'uajes sur'e un mo#elo conoci#o como C0<, este nos permite crear componentes binarios. sto quiere #ecir que yo pue#o pro'ramar un componente en $isual Aasic, y un pro'rama#or #e C@@ pue#e tomarlo y Bacer uso #e el, ya que #e por si el componente ya es c>#i'o compila#o y no c>#i'o fuente #e otro len'uaje. A partir #e esto se necesitaba or#enar, facilitar y or'ani=ar el #esarrollo #e las aplicaciones para 8in#o%s. Con esto sur'e .N !. .N ! es una solucion a to#a esa problem.tica y brin#a 'ran#es beneficios, este nos permite trabajar con c>#i'o ya e7istente, es posible Bacer uso #e los componentes C0< e incluso Bacer llama#os a la APC #e 8in#o%s. Hay una inte'raci>n fuerte entre los len'uajes, un pro'rama#or #e CD pue#e enten#er f.cilmente el c>#i'o #e un pro'rama#or #e $isual Aasic .N !, y ambos pue#en pro'ramar en el len'uaje que mas sientan como#os. sto se #ebe a que to#os los len'uajes que Bacen uso #e .N ! comparten las mismas librerias #e .N !. *a unica #ificulta# ra#ica en las #iferencias #e sinta7is entre los len'uajes, que se esta solucionan#o. .N ! es multiplataforma, po#emos ejecutar .N ! en 8in#o%s y en #iversos sistemas operativos. sto si'nifica que pue#o pro'ramar en una plataforma y mientras e7ista el runtime #e nuestra aplicaci>n para cualquier otro sistema operativo, el pro'rama se ejecutara. Co)ponentes .NET C2& ,Co))on 2!n *! e r*nti)eSe trata #e un pro'rama #e ejecuci>n comun en to#os los len'uajes. ste pro'rama lee el c>#i'o 'enera#o por el compila#or y empie=a su ejecuci>n, sin importar si el pro'rama fue crea#o con CD o con $isual Aasic .N ! o al'un otro len'uaje. l C*( lo lee y lo ejecuta. Asse)bly Cuan#o tenemos un pro'rama escrito en un len'uaje .N ! y lo compilamos se 'enera el Assembly, que contiene el pro'rama compila#o que conocemos como CC* ECommon Cnterme#iate *an'ua'eF, y tambien informaci>n sobre to#os los tipos que se utili=an en el pro'rama. C.2 *os pro'ramas #e .N ! no se compilan #irectamente en c>#i'o ensambla#or #el compila#or. n su lu'ar, se compilan a un len'uaje interme#io conoci#o como CC*. ste len'uaje es leG#o y ejecuta#o por el runtime. l uso #el CC* y el runtime es lo que le #a a .N ! su fle7ibili#a# y tambiHn su capaci#a# #e ser multiplataforma. l 9rame%or: .N ! tiene lo que se conoce como especificaciones comunes #e len'uaje o C*S. Son 'uias que cualquier len'uaje que #esee usar .N ! #ebe cumplir para po#er interactuar con el runtime. ;na ventaja #e esto es que si nuestro co#i'o cumple con las C*S po#emos tener interoperabili#a# con otros len'uajes, por ejemplo crean#o una librerGa en CD y que un pro'rama#or #e $isual Aasic pue#a utili=arlo sin problemas. ;no #e los puntos mas importantes #e estas 'uias es el C!S ECommon !ype SystemF. n los len'uajes #e pro'ramaci>n, cuan#o #eseamos 'uar#ar informaci>n, esta se coloca en una variable. *as variables ten#ran un tipo #enomina#o #epen#ien#o #e la info a 'uar#ar. Ca#a len'uaje 'uar#a la info en forma #iferente, ejemplo enteros con 1,bits o 32 bits. Para solucionar esto, el 9rame%or: #efine por me#io #el C!S como funcionaran los tipos en su entorno. 33 *a plataforma .N ! #e 'icroso/t es un componente #e so/t(!re que pue#e ser a?a#i#o al siste)! oper!ti0o Windo(s. Provee un e7tenso conjunto #e soluciones pre#efini#as para necesi#a#es 'enerales #e la pro r!)!ci4n #e aplicaciones, y a#ministra la ejecuci>n #e los pro'ramas escritos especGficamente con la plataforma. sta soluci>n es el pro#ucto principal en la oferta #e <icrosoft, y preten#e ser utili=a#a por la mayorGa #e las aplicaciones crea#as para la plataforma 8in#o%s. Co)ponentes *os principales componentes #el marco #e trabajo son1 l conjunto #e len'uajes #e pro'ramaci>n.

*a biblioteca de clases base o BCL. l entorno comn de ejecucin para lenguajes, o CLR por sus si'las en in'lHs.

&ebi#o a la publicaci>n #e la norma para la in/r!estr*ct*r! co)5n de len *!6es ECLI por sus si'las en in'lHsF, el #esarrollo #e len'uajes se facilita, por lo que el marco #e trabajo .N ! soporta ya m.s #e 24 len'uajes #e pro'ramaci>n y es posible #esarrollar cualquiera #e los tipos #e aplicaciones soporta#os en la plataforma con cualquiera #e ellos, lo que elimina las #iferencias que e7istGan entre lo que era posible Bacer con uno u otro len'uaje. Al'unos #e los len'uajes #esarrolla#os para el marco #e trabajo .N ! son1 CD, $isual Aasic .N !, &elpBi E0bject PascalF, C@@, 9D, 5D, Perl, PytBon, 9ortran, Prolo' Ee7isten al menos #os implementaciones, el PD1 y el Prolo'.N !2 F, Cobol y Po%erAuil#er. Common Language Runtime structura interna #el entorno #e ejecuci>n en len'uaje comIn. l C*( es el ver#a#ero nIcleo #el frame%or: #e .N !, entorno #e ejecuci>n en el que se car'an las aplicaciones #esarrolla#as en los #istintos len'uajes, amplian#o el conjunto #e servicios #el sistema operativo E82: y 82443F. Permite inte'rar proyectos en #istintos len'uajes soporta#os por la plataforma .Net, como C@@, $isual Aasic, CD, entre otros. *a Berramienta #e #esarrollo compila el c>#i'o fuente #e cualquiera #e los len'uajes soporta#os por .N ! en un c>#i'o interme#io, el CC* (Common Intermediate Language) antes conoci#o como <SC* (Microsoft Intermediate Language), similar al AJ! C0& #e 5ava. Para 'enerarlo, el compila#or se basa en la especificaci>n C*S (Common Language Specification) que #etermina las re'las necesarias para crear el c>#i'o <SC* compatible con el C*(. Para ejecutarse se necesita un se'un#o paso, un compila#or 5C! (Just In !ime) es el que 'enera el c>#i'o m.quina real que se ejecuta en la plataforma #el cliente. &e esta forma se consi'ue con .N ! in#epen#encia #e la plataforma #e Bar#%are. *a compilaci>n 5C! la reali=a el C*( a me#i#a que el pro'rama invoca mHto#os. l c>#i'o ejecutable obteni#o se almacena en la memoria cacBH #el or#ena#or, sien#o recompila#o #e nuevo s>lo en el caso #e pro#ucirse al'In cambio en el c>#i'o fuente.

C!r!cter7stic!s s el encar'a#o #e proveer lo que se llama c>#i'o a#ministra#o, es #ecir, un entorno que provee servicios autom.ticos al c>#i'o que se ejecuta. *os servicios son varia#os1 Car'a#or #e clases1 permite car'ar en memoria las clases. Compila#or <SC* a nativo1 transforma c>#i'o interme#io #e alto nivel in#epen#iente #el Bar#%are que lo ejecuta a c>#i'o #e m.quina propio #el #ispositivo que lo ejecuta. A#ministra#or #e c>#i'o1 coor#ina to#a la operaci>n #e los #istintos subsistemas #el Common *an'ua'e (untime. (ecolector #e basura1 elimina #e memoria objetos no utili=a#os autom.ticamente. <otor #e se'uri#a#1 a#ministra la se'uri#a# #el c>#i'o que se ejecuta. <otor #e #epuraci>n1 permite Bacer un se'uimiento #e la ejecuci>n #el c>#i'o aIn cuan#o se utilicen len'uajes #istintos. $erifica#or #e tipos1 controla que las variables #e la aplicaci>n usen el .rea #e memoria que tienen asi'na#o. A#ministra#or #e e7cepciones1 maneja los errores que se pro#ucen #urante la ejecuci>n #el c>#i'o. Soporte #e multiproceso EBilosF1 permite #esarrollar aplicaciones que ejecuten c>#i'o en forma paralela. mpaqueta#or #e C0<1 coor#ina la comunicaci>n con los componentes C0< para que pue#an ser usa#os por el .N ! 9rame%or:. Aiblioteca #e Clases Aase que incluye soporte para mucBas funcionali#a#es comunes en las aplicaciones.

#ibliotec! de Cl!ses #!se de .NET &ia'rama b.sico #e la Aiblioteca #e Clases Aase. *a Aiblioteca #e Clases Aase EAC* por sus si'las en in'lHsF maneja la mayorGa #e las operaciones b.sicas que se encuentran involucra#as en el #esarrollo #e aplicaciones, incluyen#o entre otras1 Cnteracci>n con los #ispositivos perifHricos <anejo #e #atos EA&0.N !F A#ministraci>n #e memoria

Cifra#o #e #atos !ransmisi>n y recepci>n #e #atos por #istintos me#ios EK<*, !CPLCPF A#ministraci>n #e componentes 8eb que corren tanto en el servi#or como en el cliente EASP.N !F <anejo y a#ministraci>n #e e7cepciones <anejo #el sistema #e ventanas Herramientas #e #esplie'ue #e 'r.ficos E"&C@F Herramientas #e se'uri#a# e inte'raci>n con la se'uri#a# #el sistema operativo <anejo #e tipos #e #atos unifica#o Cnteracci>n con otras aplicaciones <anejo #e ca#enas #e caracteres y e7presiones re'ulares 0peraciones aritmHticas <anipulaci>n #e fecBas, =onas Borarias y perio#os #e tiempo <anejo #e arre'los #e #atos y colecciones <anipulaci>n #e arcBivos #e im.'enes Aleatorie#a# "eneraci>n #e c>#i'o <anejo #e i#iomas Auto #escripci>n #e c>#i'o Cnteracci>n con el APC 8in32 o 8in#o%s APC. Compilaci>n #e c>#i'o sta funcionali#a# se encuentra or'ani=a#a por me#io #e espacios #e nombres jer.rquicos. *a Aiblioteca #e Clases Aase se clasifica, en cuatro 'rupos clave1 ASP.N ! y Servicios 8eb K<* 8in#o%s 9orms A&0.N ! .N ! Ens!)bl!dos ,Ase)bly;n ensambla#o es un compila#o K o &** que contiene c>#i'o CC* que se 'enera #es#e los #iferentes len'uajes .N !, y que es ejecuta#o por el C*(. Pue#e contener una o varias clases al i'ual que uno o varios namespaces. + *os ensambla#os pue#en tener #iferentes #ecora#ores que #efinen el entorno #e ejecuci>n #e los mismos C0<@, &C0<, (emotin', etc.

8ersiones y dependenci!s de .NET +r!)e(or9 .NET +r!)e(or9 4.5 Ca#a versi>n #e.N ! 9rame%or: contiene el Common *an'ua'e (untime EC*(F, las bibliotecas #e clases base y otras bibliotecas a#ministra#as. n este tema se #escriben las caracterGsticas clave #e .N ! 9rame%or: por versi>n, se proporciona las versiones #el C*( subyacente y los entornos #e #esarrollo asocia#os, y se i#entifican las versiones que se instalan en el sistema operativo #e 8in#o%s.

Ca#a versi>n #e .N ! 9rame%or: contiene caracterGsticas #e versiones anteriores e incorpora nuevas caracterGsticas. l C*( se i#entifica por su propio nImero #e versi>n. l nImero #e versi>n #e .N ! 9rame%or: se incrementa en ca#a versi>n, aunque la versi>n #e C*( no se incrementa ca#a ve=.Por ejemplo, .N ! 9rame%or: ), ).+, y ).+.1 contienen la versi>n ) #e C*(, mientras que .N ! 9rame%or: 2.4, 3.4, y 3.+ incluyen C*( 2.4. ENo e7iste la versi>n 3 #e C*(F. n 'eneral, no #ebe #esinstalar nin'una versi>n #e .N ! 9rame%or: que estH instala#a en el equipo, porque una aplicaci>n que use pue#e #epen#er #e una versi>n concreta y se pue#e interrumpir si se quita esa versi>n.Pue#e car'ar varias versiones #e .N ! 9rame%or: en un Inico equipo simult.neamente. sto si'nifica que pue#e instalar .N ! 9rame%or: sin tener que #esinstalar las versiones anteriores.Para obtener m.s informaci>n, vea Cntro#ucci>n a .N ! 9rame%or:. .N ! 9rame%or: ).+ es una actuali=aci>n en conte7to que reempla=a .N ! 9rame%or: ) en su equipo y, #e manera similar, .N ! 9rame%or: ).+.1 es una actuali=aci>n en conte7to a .N ! 9rame%or: ).+.&espuHs #e instalar una #e estas actuali=aciones, las aplicaciones #e .N ! 9rame%or: ) o .N ! 9rame%or: ).+ #eben se'uir ejecut.n#ose sin requerir la recompilaci>n.Sin embar'o, lo contrario no es cierto.No recomen#amos ejecutar aplicaciones #estina#as a .N ! 9rame%or: ).+.1 en .N ! 9rame%or: ).+.Se aplican las #irectrices si'uientes1 n $isual Stu#io 2413, pue#e ele'ir .N ! 9rame%or: ).+ como versi>n #e .N ! 9rame%or: #e #estino para un proyecto Eestablece la propie#a# "et(eferenceAssemblyPatBs.!ar'et9rame%or:<oni:erF para compilar el proyecto como ensambla#o o ejecutable .N ! 9rame%or: ).+. ste ensambla#o o ejecutable pue#e usarse en cualquier equipo que ten'a instala#o .N ! 9rame%or: ).+ o .N ! 9rame%or: ).+.1. n $isual Stu#io 2413, pue#e ele'ir .N ! 9rame%or: ).+.1 como versi>n #e .N ! 9rame%or: #e #estino para un proyecto Eestablece la propie#a# "et(eferenceAssemblyPatBs.!ar'et9rame%or:<oni:erF para compilar el proyecto como ensambla#o o ejecutable .N ! 9rame%or: ).+.1. ste ensambla#o o ejecutable #ebe ejecutarse solo en equipos que ten'an instala#o .N ! 9rame%or: ).+.1.;n arcBivo ejecutable que ten'a como #estino .N ! 9rame%or: ).+.1 ten#r. bloquea#o su funcionamiento en un equipo que solo ten'a instala#o y al usuario se le pe#ir. que instale .N ! 9rame%or: ).+.1.A#em.s, los ensambla#os #e .N ! 9rame%or: ).+.1 no se #eben llamar #es#e una aplicaci>n .N ! 9rame%or: ).+. s posible que al'unos cambios en .N ! 9rame%or: requieran cambios en su c>#i'o #e aplicaci>nM vea Compatibili#a# #e aplicaciones en .N ! 9rame%or: ).+ antes #e ejecutar sus aplicaciones e7istentes con .N ! 9rame%or: ).+ o .N ! 9rame%or: ).+.1.Para obtener m.s informaci>n sobre la instalaci>n #e la versi>n actual, vea Cnstalar .N ! 9rame%or: ).+.Para obtener informaci>n sobre el servicio #e soporte tHcnico #e .N ! 9rame%or:, vea PolGtica #el ciclo #e vi#a #e soporte tHcnico #e <icrosoft .N ! 9rame%or: en el sitio %eb #e soporte tHcnico #e <icrosoft. *as versiones 2.4, 3.4 y 3.+ #e .N ! 9rame%or: est.n compila#as con la misma versi>n #el C*( EC*( 2.4F. stas versiones representan los sucesivos niveles #e una Inica instalaci>n.Ca#a versi>n se compila mejora#o las versiones anteriores.No es posible ejecutar las versiones 2.4, 3.4 y 3.+ en paralelo en un equipo.Cuan#o se instala la versi>n 3.+, se obtiene autom.ticamente los niveles 2.4 y 3.4, y las aplicaciones que se compilaron para las versiones 2.4, 3.4 y 3.+ pue#en ejecutarse to#as en la versi>n 3.+.Sin embar'o, .N ! 9rame%or: ) finali=a este enfoque #e capas, por lo que las aplicaciones compila#as para 2.4. 3.4 o 3.+ no funcionar.n en la versi>n ) o posterior.A partir #e .N ! 9rame%or: ), pue#e usar el Bospe#aje en paralelo en el mismo proceso para ejecutar varias versiones #e C*( en un Inico proceso.Para obtener m.s informaci>n, vea ensambla#os y ejecuci>n simult.nea. A#em.s, si la aplicaci>n tiene como #estino la versi>n 2.4, 3.4 o 3.+, los usuarios pue#en necesitar el po#er Babilitar .N ! 9rame%or: 3.+ en un equipo #e 8in#o%s / o 8in#o%s /.1 Previe% para po#er ejecutar la aplicaci>n.Para obtener m.s informaci>n, vea Cnstalar .N ! 9rame%or: 3.+ en 8in#o%s /. CaracterGsticas e C& No tiene que instalar las versiones anteriores #e .N ! 9rame%or: o C*( antes #e instalar la versi>n m.s reciente. *a tabla si'uiente correlaciona .N ! 9rame%or:, C*( y las versiones #e $isual Stu#io y proporciona un breve revisi>n #e ca#a versi>n.!en'a en cuenta que $isual Stu#io proporciona compatibili#a# con mIltiples versiones EmultiNtar'etin'F, por lo que no est. limita#o a la versi>n #e .N ! 9rame%or: se muestra. 8ersi4n de .NET +r!)e(or9 ).+.1 ).+ ) 3.+ .ncorpor!do con el ."E $isual Stu#io 2413 $isual Stu#io 2412 $isual Stu#io 2414 $isual Stu#io "escripci4n Cncluye mejoras #e ren#imiento y #epuraci>n, compatibili#a# para el re#ireccionamiento #e enlaces autom.tico y compatibili#a# e7pan#i#a para las aplicaciones #e la !ien#a 8in#o%s. CncluGa una versi>n actuali=a#a #e C*( ), compatibili#a# para compilar aplicaciones !ien#a 8in#o%s y las actuali=aciones para 8P9, 8C9, 89 y ASP.N !. Presenta una nueva versi>n #e C*(, bibliotecas #e clases base e7pan#i#as y nuevas caracterGsticas, como <ana'e# 7tensibility 9rame%or: E< 9F, &ynamic *an'ua'e (untime E&*(F y contratos #e c>#i'o. Se a're'aron nuevas caracterGsticas, como los sitios %eb Babilita#os para A5AK y *CN6.*a

244/ 3.4 $isual Stu#io 244+ $isual Stu#io 244+ $isual Stu#io .N ! 2443 $isual Stu#io .N !

2.4

1.1 1.4

actuali=aci>n SP1 incorporaba #atos #in.micos y un peque?o conjunto #e mejoras a#icionales. sta versi>n es esencialmente .N ! 9rame%or: 2.4 con la incorporaci>n #e 8in#o%s Presentation 9oun#ation E8P9F, 8in#o%s Communications 9oun#ation E8C9F, 8in#o%s 8or:flo% 9oun#ation E89F y Car#Space.Se actuali=> con SP1 y SP2. Se incorpor> una nueva versi>n #e C*( con ampliaciones #e las bibliotecas #e clases base, que incluGan 'enHricos, colecciones #e 'enHricos y ampliaciones si'nificativas #e ASP.N !. sta versi>n se actuali=> con el SP1 y el SP2. CncluGa actuali=aciones #e ASP.N ! y A&0.N !. sta versi>n se actuali=> #os veces posteriormente, con Service Pac: 1 y ESP1F SP2. sta versi>n incorporaba tambiHn la ejecuci>n en paralelo, lo que permite que las aplicaciones #e un solo equipo ejecuten varias versiones #e C*(. ContenGa la primera versi>n #e C*( y la primera versi>n #e las bibliotecas #e clases base.

C #. NET

Propied!des y )etodos

Los mtodos representan acciones y las propiedades representan datos. Las propiedades estn pensadas para utilizarse como campos, en el sentido de que las propiedades no deberan ser computacionalmente complejas ni enerar e!ectos secundarios. "uando no se in!rinjan las si uientes instrucciones, considere la posibilidad de usar una propiedad en lu ar de un mtodo, porque a los desarrolladores con menos e#periencia les es ms !cil utilizar las propiedades.
;tilice una propie#a#, en lu'ar #e un mHto#o, si el valor #e la propie#a# est. almacena#o en la memoria #el proceso y la propie#a# s>lo proporcionarGa acceso al valor. public class EmployeeRecord { private int employeeId; private int department; public EmployeeRecord() { } public EmployeeRecord (int id, int departmentId) { EmployeeId = id; Department = departmentId; } public int Department { get {return department;} set {department = value;} } public int EmployeeId { get {return employeeId;} set {employeeId = value;} } public EmployeeRecord Clone() { return ne EmployeeRecord(employeeId, department); } }

1tilice *n ):todo; en l* !r de *n! propied!d; en l!s si *ientes sit*!ciones.

*a operaci>n es m.s lenta en varios >r#enes #e ma'nitu# #e lo que serGa el establecimiento #e un campo. Si est. consi#eran#o proporcionar una versi>n asincr>nica #e una operaci>n para evitar que se bloquee el subproceso, es muy probable que la operaci>n consuma #emasia#os recursos para ser una propie#a#. n particular, las operaciones que tienen acceso a la re# o al sistema #e arcBivos Esalvo una ve= para la iniciali=aci>nF probablemente #eberGan ser mHto#os, no propie#a#es. *a operaci>n es una conversi>n, como el !b"ect#$o%tring met&od. *a operaci>n #evuelve un resulta#o #istinto ca#a ve= que se la llama, aun cuan#o los par.metros no cambian. Por ejemplo, el mHto#o Ne%"ui# #evuelve un valor #iferente ca#a ve= que se lo llama. *a operaci>n tiene un efecto secun#ario si'nificativo y notable. 0bserve que rellenar una cacBH interna no se suele consi#erar como un efecto secun#ario notable. *a operaci>n #evuelve una copia #e un esta#o interno Eesto no incluye las copias #e objetos #e tipo #e valor #evueltas a la pilaF. *a operaci>n #evuelve una matri=.

C!)pos y )ie)bros

1n c!)po es una variable #e cualquier tipo que se #eclara #irectamente en una clase o estructura. *os campos son miembros #e su tipo contene#or. ;na clase o estructura pue#e tener campos #e instancia, campos est.ticos o ambos. *os campos #e instancia son especGficos #e una instancia #e un tipo. Si tiene una clase !, con un campo #e instancia 9, pue#e crear #os objetos #e tipo ! y mo#ificar el valor #e 9 en ca#a objeto sin afectar al valor #el otro objeto. Por el contrario, un campo est.tico pertenece a la propia clase y se comparte entre to#as las instancias #e #icBa clase. *os cambios reali=a#os en la instancia A ser.n inme#iatamente visibles en las instancias A y C si tienen acceso al campo. Por re'la 'eneral, solo #ebe utili=ar campos para variables con accesibili#a# priva#a o prote'i#a. *os #atos que la clase e7pone al c>#i'o #e cliente se #eben proporcionar a travHs #e mHto#os, propie#a#es e in#i=a#ores. Si se utili=an estas construcciones para el acceso in#irecto a campos internos, se establece una protecci>n ante valores #e entra#a no v.li#os. ;n campo priva#o que almacena los #atos e7puestos por una propie#a# pIblica se #enomina #ispositivo #e copia #e se'uri#a# o campo #e respal#o. *os campos se pue#en marcar como public, private, protecte#, internal o protecte# internal. stos mo#ifica#ores #e acceso #efinen c>mo pue#en tener acceso a los campos los usuarios #e la clase ;n campo pue#e #eclararse #e forma opcional como static. sto Bace que el campo estH siempre #isponible para los llama#ores, aunque no e7ista nin'una instancia #e la clase.
%

;n campo pue#e #eclararse como rea#only. Solo es posible asi'nar un valor a un campo #e tipo rea#only #urante la iniciali=aci>n o en un constructor. ;n campo static rea#only es muy similar a una constante, e7cepto en que el compila#or #e CD no tiene acceso a Hl en tiempo #e compilaci>n, solo en tiempo #e ejecuci>n. Todos los ):todos; c!)pos; const!ntes; propied!des y e0entos se deben decl!r!r dentro de *n tipo< estos ele)entos se deno)in!n )ie)bros de l! cl!se o estr*ct*r!. En C#; no e=isten 0!ri!bles ni ):todos lob!les co)o en otros len *!6es. .ncl*so el p*nto de entr!d! de *n pro r!)!; el ):todo '!in; se debe decl!r!r dentro de *n! cl!se o estr*ct*r!. En l! list! si *iente se incl*yen los di0ersos tipos de )ie)bros >*e p*eden decl!r!rse en *n! cl!se o en *n! estr*ct*r!. Campos, Constantes,Propie#a#es,<Hto#os ,Constructores ,&estructores , ventos ,Cn#i=a#ores,0pera#ores ,!ipos ani#a#os
Esp!cios de no)bres ,n!)esp!ces-

*os espacios #e nombres se utili=an en 'ran me#i#a en la pro'ramaci>n #e CD #e #os maneras. n primer lu'ar, .N ! 9rame%or: utili=a los espacios #e nombres para or'ani=ar sus mIltiples clases, #e la forma si'uiente1
%ystem#Console#'rite(ine()*ello 'orld+));

&ystem es un espacio de nombres y "onsole es una clase de ese espacio de nombres.

n se'un#o lu'ar, #eclarar espacios #e nombres propios pue#e ayu#ar a controlar el .mbito #e clase y nombres #e mHto#o en proyectos #e pro'ramaci>n 'ran#es. ;tilice la palabra clave namespace para #eclarar un espacio #e nombres, como en el ejemplo si'uiente1
namespace %ample,amespace { class %ampleClass { public void %ample-et&od() { %ystem#Console#'rite(ine( )%ample-et&od inside %ample,amespace)); } } }

*os espacios #e nombres tienen las propie#a#es si'uientes1


0r'ani=an proyectos #e c>#i'o #e 'ran tama?o. l opera#or . #elimita los espacios #e nombres. usin' #irective Bace que no sea necesario especificar el nombre #el espacio #e nombres para ca#a clase. l espacio #e nombres 'lobal es el espacio #e nombres OraG=O1 'lobal11System siempre Bar. referencia al espacio #e nombres System #e .N ! 9rame%or:.

'

*os espacios #e nombres son una manera #e or'ani=ar los #istintos tipos que aparecen en un pro'rama en CD. Conceptualmente es similar a una carpeta en un sistema #e arcBivo #el equipo. Al i'ual que las carpetas, los espacios #e nombres permiten a las clases tener un nombre completo Inico. ;n pro'rama en CD contiene uno o m.s espacios #e nombres, que que#an #efini#os por el pro'rama#or o como parte #e una biblioteca #e clases previamente escrita. Por ejemplo, el espacio #e nombres System incluye la clase Console, una clase que contiene los mHto#os para leer y escribir en la ventana #e la consola. l espacio #e nombres System tambiHn contiene mIltiples espacios #e nombres #iferentes, como System.C0 y System.Collections. S>lo .N ! 9rame%or: tiene m.s #e ocBenta espacios #e nombres, ca#a uno con miles #e clases1 los espacios #e nombres se utili=an para minimi=ar la confusi>n que se po#rGa pro#ucir entre tipos y mHto#os con nombres pareci#os. Si escribe una clase fuera #e una #eclaraci>n #e espacio #e nombres, el compila#or proporcionar. un espacio #e nombres pre#etermina#o para esa clase.
Los namespaces le hacen ms fcil para proponer los nicos nombres. Imagina cuan difcil sera nombrar a su prximo hijo si el nombre tendra que ser nico de acuerdo a la cara de ste? je je je... La singularidad restringida a un contexto ms limitado como mi conjunto de hijos simplifica las cosas tremendamente. !uando "o nombre a mi prximo ni#o mi nica consideracin es que "o no use el mismo nombre que us para uno de mis otros ni#os. $ebe tenerse en cuenta que otro puesto de padres puede escoger el mismo nombre que "o escoj para uno de mis hijos pero esos nombres sern parte de namespaces distinto " por consiguiente puede distinguirse fcilmente. Un namespace debe asegurar la singularidad de sus miembros Ni0eles de !ccesibilid!d

;tilice los mo#ifica#ores #e acceso, public, protecte#, internal o private para especificar una #e las si'uientes accesibili#a#es #eclara#as para miembros.

!o#os los tipos y miembros #e tipo tienen un nivel #e accesibili#a#, que controla si pue#en utili=arse por otro c>#i'o #e su ensambla#o u otros ensambla#os. *a accesibili#a# #e un tipo o miembro se especifica al #eclararlo utili=an#o uno #e estos mo#ifica#ores #e acceso1
public Pue#e obtener acceso al tipo o miembro cualquier otro c>#i'o #el mismo ensambla#o o #e otro ensambla#o que Ba'a referencia a Hste. pri(ate Solamente pue#e obtener acceso al tipo o miembro c>#i'o #e la misma clase o estructura.

protected Solamente pue#e obtener acceso al tipo o miembro c>#i'o #e la misma clase o estructura o #e una clase #eriva#a. internal Pue#e obtener acceso al tipo o miembro cualquier c>#i'o #el mismo ensambla#o, pero no #e un ensambla#o #istinto. protected internal Pue#e obtener acceso al tipo o miembro cualquier c>#i'o #el mismo ensambla#o o cualquier clase #eriva#a #e otro ensambla#o.

Protected *a palabra clave protecte# es un mo#ifica#or #e acceso a miembros. ;n miembro prote'i#o es accesible #entro #e su clase y por instancias #e clases #eriva#as. ncontrar. una comparaci>n #e protecte# con los otros mo#ifica#ores #e acceso en Niveles #e accesibili#a#.

.ntern!l

1*

*a palabra clave internal es un mo#ifica#or #e acceso para tipos y miembros #e tipos. *os tipos o miembros internos s>lo son accesibles #entro #e los arcBivos #el mismo ensambla#o, como en este ejemplo1 public class AaseClass P LL 0nly accessible %itBin tBe same assembly internal static int 7 Q 4M R S>lo se permite un mo#ifica#or #e acceso para un miembro o tipo, e7cepto cuan#o se utili=a la combinaci>n protecte#internal. *os mo#ifica#ores #e acceso no se pue#en utili=ar en espacios #e nombres. *os espacios #e nombres no presentan restricciones #e acceso. Se'In el conte7to en el que se pro#uce una #eclaraci>n #e miembro, s>lo se permite #eclarar ciertos tipos #e acceso. Si no se especifica nin'In mo#ifica#or #e acceso en una #eclaraci>n #e miembro, se utili=a el tipo #e acceso pre#etermina#o. *os tipos #e nivel superior, que no est.n ani#a#os en otros tipos, s>lo pue#en tener accesibili#a# internal o public. *a accesibili#a# pre#etermina#a para estos tipos es internal.

Accesibilid!d ! cl!ses y estr*ct*r!s

*as clases y estructuras #eclara#as #irectamente en un espacio #e nombres Ees #ecir, que no se ani#an #entro #e otras clases o estructurasF pue#en ser pIblicas o internas. Si no se especifica un mo#ifica#or #e acceso, internal es el valor pre#etermina#o. *as clases y estructuras ani#a#as tambiHn pue#en #eclararse como priva#as. No se pue#e obtener acceso a tipos ani#a#os priva#os #es#e el tipo contene#or. *as clases #eriva#as no pue#en tener mayor accesibili#a# que sus tipos base. n otras palabras, no pue#e tener una clase pIblica A que se #erive #e una clase interna A. Si se permitiera, A se BarGa pIblica, porque se pue#e obtener acceso a to#os los miembros internos o prote'i#os #e A #es#e la clase #eriva#a. Pue#e permitir a otros ensambla#os concretos el acceso a sus tipos internos utili=an#o el atributo Cnternals$isible!o. Accesibilid!d de *n )ie)bro de cl!se y estr*ct*r!

*os miembros #e clase Eincluyen#o clases y estructuras ani#a#asF pue#en #eclararse con cualquiera #e los cinco tipos #e acceso. *os miembros #e estructura no pue#en #eclararse como prote'i#os porque las estructuras no a#miten la Berencia. *a accesibili#a# #e un miembro nunca pue#e ser mayor que la #e su tipo contene#or. Por ejemplo, un mHto#o pIblico #eclara#o en un tipo interno s>lo tiene accesibili#a# interna. Cuan#o un miembro #e una clase o estructura es una propie#a#, campo, mHto#o, evento o #ele'a#o y #icBo miembro es un tipo o tiene un tipo como par.metro o valor #evuelto, la accesibili#a# #el miembro no pue#e ser mayor que la #el tipo. Por ejemplo, no pue#e tener un mHto#o pIblico < que #evuelva una clase C a menos que C sea tambiHn pIblica. &e i'ual forma, no pue#e tener una propie#a# prote'i#a #e tipo A si A se #eclara como priva#o. *os opera#ores #efini#os por el usuario siempre #eben #eclararse como pIblicos. Para obtener m.s informaci>n, vea operator E(eferencia #e CDF. *os #estructores no pue#en tener mo#ifica#ores #e accesibili#a#.

11

Sentenci! 1sin

Proporciona una sinta7is a#ecua#a que 'aranti=a el uso correcto #e los objetos C&isposable. E6e)plo usin' ESystem.C0.Stream(ea#er sr Q ne% System.C0.Stream(ea#erESOC1T;sersTPublicT&ocumentsTtest.t7tOFF P strin' s Q nullM %BileEEs Q sr.(ea#*ineEFF UQ nullF P Console.8rite*ineEsFM R R usin' E!ransactionScope scope Q ne% !ransactionScopeEFF P oCnn Q Cone7ion.0btenerConne7ionS6*EFM cm#.Comman#!e7t Q OCar'o2"rabarOM oCnn.0penEFM cm#.Comman#!ype Q Comman#!ype.Store#Proce#ureM cm#.Parameters.A##Ene% SqlParameterEOSC;C*O, unCar'o.C;C*FFM cm#.Parameters.A##Ene% SqlParameterEOSC; O, unCar'o. scuela.C; FFM cm#.Parameters.A##Ene% SqlParameterEOSCpO, ;tils."et;suarioEF.CpFFM cm#.Connection Q oCnnM cm#. 7ecuteNon6ueryEFM LLAu#itoria Anses.ConC'.;tiles.Se'uri#a#*o'&A0."uar#ar*o'EOCar'oO, OCO, cm#.ParametersFM scope.CompleteEFM return trueM R E6e)plo public static bool "rabarECar'o unCar'oF P SqlConnection oCnn Q ne% SqlConnectionEFM SqlComman# cm# Q ne% SqlComman#EFM try P usin' E!ransactionScope scope Q ne% !ransactionScopeEFF P oCnn Q Cone7ion.0btenerConne7ionS6*EFM cm#.Comman#!e7t Q OCar'o2"rabarOM oCnn.0penEFM cm#.Comman#!ype Q Comman#!ype.Store#Proce#ureM cm#.Parameters.A##Ene% SqlParameterEOSC;C*O, unCar'o.C;C*FFM cm#.Parameters.A##Ene% SqlParameterEOSC; O, unCar'o. scuela.C; FFM cm#.Parameters.A##Ene% SqlParameterEOSApelli#oyNombreO, unCar'o.Apelli#oyNombreFFM cm#.Parameters.A##Ene% SqlParameterEOSC#!ipoCar'oO, unCar'o.!ipoCar'oFFM cm#.Parameters.A##Ene% SqlParameterEOS;suarioO, ;tils."et;suarioEF.;suario&escFFM cm#.Parameters.A##Ene% SqlParameterEOS0ficinaCar'aO, ;tils."et;suarioEF.0ficinaFFM cm#.Parameters.A##Ene% SqlParameterEOSCpO, ;tils."et;suarioEF.CpFFM cm#.Connection Q oCnnM cm#. 7ecuteNon6ueryEFM scope.CompleteEFM return trueM

12

R R catcB E 7ception errF P tBro% errM R finally P if EoCnn.State UQ ConnectionState.Close#F P oCnn.CloseEFM R oCnn.&isposeEFM cm#.&isposeEFM R R

9ile y 9ont son ejemplos #e tipos a#ministra#os que obtienen acceso a recursos no a#ministra#os Een este caso, i#entifica#ores #e arcBivo y conte7tos #e #ispositivoF. 7isten mucBos m.s tipos #e recursos no a#ministra#os y tipos #e biblioteca #e clases que los encapsulan. !o#os estos tipos #eben implementar la interfa= C&isposable. Como norma, cuan#o utilice un objeto C&isposable, #ecl.relo y cree instancias #el mismo en una instrucci>n usin'. *a instrucci>n usin' llama al mHto#o &ispose en el objeto #e la forma correcta y, si se utili=a tal y como se Ba e7plica#o anteriormente, tambiHn Bace que el propio objeto sal'a #el .mbito en cuanto se llama a &ispose. &entro #el bloque usin', el objeto es #e s>lo lectura y no pue#e mo#ificarse ni reasi'narse. *a instrucci>n usin' 'aranti=a que se llame a &ispose, aunque se pro#u=ca una e7cepci>n mientras se llama a los mHto#os #el objeto. Pue#e conse'uir el mismo resulta#o colocan#o el objeto #entro #e un bloque try y llaman#o a continuaci>n a &ispose en un bloque finallyM #e BecBo, esta es la forma en que el compila#or tra#uce la instrucci>n usin'. l ejemplo #e c>#i'o anterior se e7tien#e al si'uiente c>#i'o en tiempo #e compilaci>n Eten'a en cuenta las llaves a#icionales para crear el .mbito limita#o #el objetoF1 .nter/!? ."ispos!ble

&efine un mHto#o para liberar los recursos asi'na#os. VCom$isibleAttributeEtrueFW public interface C&isposable sta interfa= se usa principalmente para liberar los recursos no a#ministra#os. l recolector #e elementos no utili=a#os libera autom.ticamente la memoria asi'na#a a un objeto a#ministra#o cuan#o ya no se utili=a ese objeto. Sin embar'o, no se pue#e prever cu.n#o se pro#ucir. la recolecci>n #e elementos no utili=a#os. A#em.s, el recolector #e elementos no utili=a#os no reconoce recursos no a#ministra#os tales como los i#entifica#ores #e ventana, o las secuencias y arcBivos abiertos. ;tilice el mHto#o &ispose #e esta interfa= para liberar recursos no a#ministra#os e7plGcitamente junto con el recolector #e elementos no utili=a#os. l consumi#or #e un objeto pue#e llamar a este mHto#o cuan#o el objeto #eja #e ser necesario E6e)plo: LL &eclare #ele'ate NN #efines require# si'nature1 #ele'ate #ouble <atBActionE#ouble numFM class &ele'ate!est P LL (e'ular metBo# tBat matcBes si'nature1 static #ouble &oubleE#ouble inputF P return input X 2M R

13

static voi# <ainEF P LL Cnstantiate #ele'ate %itB name# metBo#1 <atBAction ma Q &oubleM LL Cnvo:e #ele'ate ma1 #ouble multAy!%o Q maE).+FM Console.8rite*ineEmultAy!%oFM LL Cnstantiate #ele'ate %itB anonymous metBo#1 <atBAction ma2 Q #ele'ateE#ouble inputF P return input X inputM RM #ouble square Q ma2E+FM Console.8rite*ineEsquareFM LL Cnstantiate #ele'ate %itB lamb#a e7pression <atBAction ma3 Q s QY s X s X sM #ouble cube Q ma3E).3-+FM Console.8rite*ineEcubeFM R R

Cl!ses y ):todos p!rci!les

+s posible di(idir la de!inici,n de una clase, estructura, inter!az o mtodo en dos o ms arc-i(os de c,di o !uente. "ada arc-i(o de c,di o !uente contiene una secci,n de la de!inici,n de tipos o mtodos, y todas las partes se combinan cuando se compila la aplicaci,n.

Clases parciales1 7isten #iversas situaciones en las que es conveniente #ivi#ir una #efinici>n #e clase1

Al trabajar en proyectos 'ran#es, el BecBo #e #ivi#ir una clase en arcBivos in#epen#ientes permite que varios pro'rama#ores trabajen al mismo tiempo con ella. Al trabajar con un c>#i'o fuente 'enera#o autom.ticamente, se pue#e a're'ar el c>#i'o a la clase sin tener que volver a crear el arcBivo #e c>#i'o fuente. $isual Stu#io utili=a este enfoque al crear formularios 8in#o%s 9orms, c>#i'o contene#or #e un servicio %eb, etc. Se pue#e crear c>#i'o que utilice estas clases sin tener que mo#ificar el arcBivo crea#o por $isual Stu#io. Para #ivi#ir una #efinici>n #e clase, utilice el mo#ifica#or partial, como se muestra a continuaci>n1

public partial class Employee { public void Do'or.() { } } public partial class Employee { public void /o$o(unc&() { }

14

*a palabra clave partial in#ica que otras partes #e la clase, estructura o interfa= se pue#en #efinir en el espacio #e nombres. !o#as las partes #eben utili=ar la palabra clave partial. !o#as las partes #eben estar #isponibles en tiempo #e compilaci>n para formar el tipo final. !o#as las partes #eben tener la misma accesibili#a#, ya sea public, private, etc. Si al'una parte se #eclara abstracta, to#o el tipo se consi#era abstracto. Si al'una parte se #eclara seale#, to#o el tipo se consi#era seale#. Si al'una parte #eclara un tipo base, to#o el tipo Bere#a esa clase. !o#as las partes que especifican una clase base #eben concor#ar, pero las partes que omiten una clase base Bere#an i'ualmente el tipo base. *as partes pue#en especificar #iferentes interfaces base, pero el tipo final implementa to#as las interfaces mostra#as por to#as las #eclaraciones parciales. Cualquier miembro #e clase, estructura o interfa= #eclara#o en una #efinici>n parcial est. #isponible para to#as las #em.s partes. l tipo final es la combinaci>n #e to#as las partes en tiempo #e compilaci>n.
Str*ct y cl!ses

*as estructuras se #iferencian #e las clases #e #iferentes maneras1


Las estructuras son tipos de (alor .odos los tipos de estructura se -eredan implcitamente de la clase %ystem#0alue$ype La asi naci,n a una (ariable de un tipo de estructura crea una copia del (alor que se asi ne +l (alor predeterminado de una estructura es el (alor producido al establecer todos los campos de tipos de (alor en su (alor predeterminado, y todos los campos de tipos de re!erencia en null Las operaciones bo#in y unbo#in se utilizan para realizar la con(ersi,n entre un tipo struct y un tipo
ob"ect

+l si ni!icado de t&is es di!erente para las estructuras Las declaraciones de campos de instancia para una estructura no pueden incluir inicializadores de (ariable /na estructura no puede declarar un constructor de instancia sin parmetros /na estructura no puede declarar un destructor.

*as estructuras son tipos #e valor ESecci>n ).1F y se #ice que tienen sem.nticas #e valor. *as clases, por el contrario, son tipos #e referencia ESecci>n ).2F y se #ice que tienen sem.ntica #e referencia. ;na variable #e un tipo #e estructura contiene #irectamente los #atos #e la estructura, mientras que una variable #e un tipo #e clase contiene una referencia a los #atos, que se conocer. posteriormente como objeto. n el caso #e las clases, es posible que #os variables Ba'an referencia al mismo objeto y, por tanto, que las operaciones en una variable afecten al objeto al que Bace referencia la otra variable. n el caso #e las estructuras, ca#a variable tiene su propia copia #e los #atos Ee7ceptuan#o las variables #e los par.metros ref y outF, #e manera que no posible que las operaciones #e una afecten a la otra. &a#o que las estructuras no son tipos #e referencia, no es posible que los valores #e un tipo #e estructura sean null.
15

&a#a la #eclaraci>n
struct 1oint { public int 2, y; public 1oint(int 2, int y) { t&is#2 = 2; t&is#y = y; } }

el fra'mento #e c>#i'o
1oint a = ne 1oint(34, 34); 1oint b = a; a#2 = 344; %ystem#Console#'rite(ine(b#2);

#evuelve como resulta#o el valor 34. *a asi'naci>n #e a a b crea una copia #el valor y por tanto b no se ve afecta#a por la asi'naci>n a a#2. n cambio, si se Bubiera #eclara#o 1oint como clase, el resulta#o serGa 344 puesto que a y b BarGan referencia al mismo objeto. l tipo str*ct es a#ecua#o para representar objetos #e poca compleji#a#, como Point, &ect!n le y Color. Aunque es posible representar un punto como una clase, una estructura es m.s efica= en al'unos casos. Por ejemplo, si #eclara una matri= #e 1444 objetos Point, asi'nar. memoria a#icional para Bacer referencia a ca#a objetoM en este caso, una estructura serGa menos costosa. Puesto que .N ! 9rame%or: contiene un objeto #enomina#o Point, llamaremos en su lu'ar a la estructura OCo0r#sO.
"0
public struct Co!rds { public int 2, y; public Co!rds(int p3, int p5) { 2 = p3; y = p5; } }

s un error #eclarar un constructor pre#etermina#o Esin par.metrosF para una estructura. Siempre e7iste un constructor pre#etermina#o que iniciali=a los miembros #e la estructura con sus valores pre#etermina#os. !ambiHn es un error iniciali=ar un campo #e instancia en una estructura. Cuan#o se crea un objeto struct me#iante el opera#or ne%, se crea y se llama al constructor apropia#o. A #iferencia #e las clases, es posible crear instancias #e las estructuras sin utili=ar el opera#or ne(. Si no se utili=a ne(, los campos permanecer.n sin asi'nar y el objeto no se po#r. utili=ar Basta Baber iniciali=a#o to#os los campos. A #iferencia #e las clases, para las estructuras no e7iste Berencia. ;na estructura no pue#e Bere#ar #e otra estructura o clase, ni pue#e ser la base #e una clase. Sin embar'o, las estructuras Bere#an #e la clase base 0bject. ;na estructura pue#e implementar interfaces #el mismo mo#o que las clases.
Enc!ps*l!)iento

1$

+n ocasiones se -ace re!erencia a la encapsulaci,n como el primer pilar o principio de la pro ramaci,n orientada a objetos. &e 1n el principio de encapsulaci,n, una clase o una estructura puede especi!icar el ni(el posible de acceso a cada uno de sus miembros en el c,di o !uera de la clase o la estructura. Los mtodos y (ariables que no se (an a utilizar !uera de la clase o el ensamblado se pueden ocultar para limitar la posibilidad de errores de codi!icaci,n o ataques malintencionadas.
@erenci! en c#

-erencia permite crear nue(as clases que reutilizan, e#tienden y modi!ican el comportamiento que se de!ine en otras clases. La clase cuyos miembros se -eredan se denomina clase base y la clase que -ereda esos miembros se denomina clase deri(ada. Las estructuras no admiten la -erencia pero pueden implementar inter!aces.

Conceptualmente, una clase #eriva#a es una especiali=aci>n #e la clase base. Por ejemplo, si tiene una clase base Animal, pue#e tener una clase #eriva#a #enomina#a <ammal y otra clase #eriva#a #enomina#a (eptile. <ammal es Animaly (eptile es Animal, pero ca#a clase #eriva#a representa especiali=aciones #iferentes #e la clase base. Al #efinir una clase para #erivar #e otra clase, la clase #eriva#a obtiene implGcitamente to#os los miembros #e la clase base, salvo sus constructores y #estructores. *a clase #eriva#a pue#e, por tanto, reutili=ar el c>#i'o #e la clase base sin tener que volver a implementarlo. n la clase #eriva#a, pue#e a're'ar m.s miembros. &e esta manera, la clase #eriva#a e7tien#e la funcionali#a# #e la clase base. Cuan#o una clase base #eclara un mHto#o como virtual, una clase #eriva#a pue#e invali#ar el mHto#o con su propia implementaci>n. Si una clase base #eclara un miembro como abstracto, ese mHto#o se #ebe invali#ar en cualquier clase no abstracta que Bere#e #irectamente #e #icBa clase. Si una clase #eriva#a es abstracta en sG misma, Bere#a los miembros abstractos sin implementarlos. *os miembros abstractos y virtuales son la base para el polimorfismo, la se'un#a caracterGstica principal #e la pro'ramaci>n orienta#a a objetos. Pue#e #eclarar una clase como abstracta si #esea evitar la creaci>n #irecta #e instancias por me#io #e la palabra clave ne%. Si Bace esto, la clase solo se pue#e utili=ar si una nueva clase se #eriva #e ella. ;na clase abstracta pue#e contener una o m.s firmas #e mHto#o que se #eclaran a sG mismas como abstractas. stas firmas especifican los par.metros y el valor #evuelto pero no tienen nin'una implementaci>n Ecuerpo #el mHto#oF. ;na clase abstracta no tiene que contener miembros abstractosM sin embar'o, si una clase contiene un miembro abstracto, la propia clase se #ebe #eclarar como abstracta. *as clases #eriva#as que no son abstractas por sG mismas #eben proporcionar la implementaci>n #e cualquier mHto#o abstracto #e una clase base abstracta.

Poli)or/is)o

A menu#o se Bace referencia al polimorfismo como el tercer pilar #e la pro'ramaci>n orienta#a a objetos, tras la encapsulaci>n y la Berencia. l tHrmino polimorfismo es una palabra 'rie'a que si'nifica Ocon mucBas formasO y tiene #os aspectos que lo caracteri=an1 1. n tiempo #e ejecuci>n, los objetos #e una clase #eriva#a se pue#en tratar como objetos #e una clase base en lu'ares como par.metros #e mHto#o y colecciones o matrices. Cuan#o esto suce#e, el tipo #eclara#o #el objeto ya no es i#Hntico a su tipo en tiempo #e ejecuci>n.
1%

2. *as clases base pue#en #efinir e implementar mHto#os virtuales y las clases #eriva#as pue#en invali#arlos, lo que si'nifica que proporcionan su propia #efinici>n e implementaci>n. n tiempo #e ejecuci>n, cuan#o el c>#i'o #e cliente llama al mHto#o, C*( busca el tipo en tiempo #e ejecuci>n #el objeto e invoca esta invali#aci>n #el mHto#o virtual. AsG, en el c>#i'o fuente pue#e llamar a un mHto#o #e una clase base y provocar la ejecuci>n #e la versi>n #e clase #eriva#a #el mHto#o. *os mHto#os virtuales permiten trabajar con 'rupos #e objetos relaciona#os #e una manera uniforme. Por ejemplo, supon'a que #ispone #e una aplicaci>n #e #ibujo que permite a un usuario crear varios tipos #e formas en una superficie #e #ibujo. n tiempo #e compilaci>n no conoce los tipos especGficos #e formas que crear. el usuario. Sin embar'o, la aplicaci>n tiene que reali=ar el se'uimiento #e los #iferentes tipos #e formas que se crean y tiene que actuali=arlos como respuesta a las acciones #el mouse #el usuario. Pue#e utili=ar el polimorfismo para resolver este problema en #os pasos b.sicos1 1. Cree una jerarquGa #e clases en la que ca#a clase #e forma especGfica #erive #e una clase base comIn. 2. ;tilice un mHto#o virtual para invocar el mHto#o a#ecua#o #e una clase #eriva#a a travHs #e una Inica llama#a al mHto#o #e clase base. n primer lu'ar, cree una clase base llama#a SBape y clases #eriva#as como (ectan'le, Circle y !rian'le. Cncluya en la clase SBape un mHto#o virtual llama#o &ra% e invalG#elo en ca#a clase #eriva#a para #ibujar la forma #etermina#a que representa la clase. Cree un objeto *istZSBapeY y a're'ue elementos Circle, !rian'le y (ectan'le a Hl. Para actuali=ar la superficie #e #ibujo, utilice un bucle foreacB para recorrer en iteraci>n la lista y llamar al mHto#o &ra% en ca#a objeto SBape #e la lista. Aunque ca#a objeto #e la lista tiene un tipo #eclara#o #e SBape, es el tipo en tiempo #e ejecuci>n Ela versi>n invali#a#a #el mHto#o en ca#a clase #eriva#aF el que se invocar..
"0
public class %&ape { 66 7 8e e2ample members public int 9 { get; private set; } public int : { get; private set; } public int *eig&t { get; set; } public int 'idt& { get; set; } 66 0irtual met&od public virtual void Dra () { Console#'rite(ine()1er8orming base class dra ing tas.s)); } } class Circle ; %&ape { public override void Dra () { 66 Code to dra a circle### Console#'rite(ine()Dra ing a circle)); base#Dra (); } } class Rectangle ; %&ape { public override void Dra () { 66 Code to dra a rectangle### Console#'rite(ine()Dra ing a rectangle)); base#Dra ();

1'

} } class $riangle ; %&ape { public override void Dra () { 66 Code to dra a triangle### Console#'rite(ine()Dra ing a triangle)); base#Dra (); } } class 1rogram { static void -ain(string<= args) { 66 1olymorp&ism at or. >3; a Rectangle, $riangle and Circle 66 can all be used &ereever a %&ape is e2pected# ,o cast is 66 re?uired because an implicit conversion e2ists 8rom a derived 66 class to its base class# %ystem#Collections#/eneric#(ist@%&apeA s&apes = ne %ystem#Collections#/eneric#(ist@%&apeA(); s&apes#7dd(ne Rectangle()); s&apes#7dd(ne $riangle()); s&apes#7dd(ne Circle()); 66 1olymorp&ism at or. >5; t&e virtual met&od Dra is 66 invo.ed on eac& o8 t&e derived classes, not t&e base class# 8oreac& (%&ape s in s&apes) { s#Dra (); } 66 Beep t&e console open in debug mode# Console#'rite(ine()1ress any .ey to e2it#)); Console#ReadBey();

} }

6C !utput; Dra ing a rectangle 1er8orming base class dra ing tas.s Dra ing a triangle 1er8orming base class dra ing tas.s Dra ing a circle 1er8orming base class dra ing tas.s C6

Miembros virtuales

Cuan#o una clase #eriva#a Bere#a #e una clase base, obtiene to#os los mHto#os, campos, propie#a#es y eventos #e la clase base. l #ise?a#or #e la clase #eriva#a pue#e ele'ir si

invali#a los miembros virtuales #e la clase base Bere#a el mHto#o #e clase base m.s pareci#o sin invali#arlo
1)

#efine una nueva implementaci>n no virtual #e los miembros que ocultan las implementaciones #e la clase base

;na clase #eriva#a solo pue#e invali#ar un miembro #e la clase base si Hste se #eclara como virtual o abstracto. l miembro #eriva#o #ebe utili=ar la palabra clave overri#e para in#icar e7plGcitamente que el mHto#o va a participar en la invocaci>n virtual. l c>#i'o si'uiente proporciona un ejemplo1
(os campos no pueden ser virtuales# %olo los mDtodos, propiedades, eventos e indiEadores pueden serlo# Cuando una clase derivada reemplaEa un miembro virtual, se llama a ese miembro aun?ue se tenga acceso a una instancia de esa clase como instancia de la clase base# El cFdigo siguiente proporciona un e"emplo;

DerivedClass G = ne DerivedClass(); G#Do'or.(); 66 Calls t&e ne met&od# GaseClass 7 = (GaseClass)G; 7#Do'or.(); 66 7lso calls t&e ne met&od#

(os mDtodos y propiedades virtuales permiten a las clases derivadas e2tender una clase base sin necesidad de utiliEar la implementaciFn de clase base de un mDtodo#

Evitar que las clases derivadas invaliden los miembros virtuales

*os miembros virtuales si'uen sien#o virtuales #e forma in#efini#a, in#epen#ientemente #e cu.ntas clases se Bayan #eclara#o entre el miembro virtual y la clase que ori'inalmente lo #eclar>. Si la clase A #eclara un miembro virtual, la clase A #eriva #e A y la clase C #eriva #e A, la clase C Bere#a el miembro virtual y tiene la opci>n #e reempla=arlo, in#epen#ientemente #e si la clase A #eclar> la sustituci>n #e ese miembro.
Hna clase derivada puede detener la &erencia virtual si la invalidaciFn se declara como sealed# 1ara ello es necesario incluir la palabra clave sealed antes de la palabra clave override en la declaraciFn del miembro de clase# El mDtodo Do'or. ya no es virtual para ninguna clase derivada de C# $odavIa es virtual para instancias de C, aun?ue se conviertan al tipo G o 7# (os mDtodos sellados se pueden reemplaEar por clases derivadas mediante la palabra clave ne

*a palabra clave abstract permite crear clases y miembros #e clase que est.n incompletos y se #eben implementar en una clase #eriva#a. *a palabra clave seale# permite impe#ir la Berencia #e una clase o #e ciertos miembros #e clase marca#os previamente como virtuales. ;na clase sella#a no se pue#e utili=ar como clase base. Por esta ra=>n, tampoco pue#e ser una clase abstracta. *as clases sella#as evitan la #erivaci>n. Puesto que nunca se pue#en utili=ar como una clase base, al'unas optimi=aciones en tiempo #e ejecuci>n pue#en Bacer que sea un poco m.s r.pi#o llamar a miembros #e clase sella#a. ;n miembro #e clase, mHto#o, campo, propie#a# o evento #e una clase #eriva#a que reempla=a a un miembro virtual #e la clase base pue#e #eclarar ese miembro como sella#o. sto nie'a el aspecto virtual #el miembro para cualquier clase #eriva#a a#icional. sto se lo'ra colocan#o la palabra clave seale# antes #e la palabra clave overri#e en la #eclaraci>n #el miembro #e clase.
2*

.nter/!ces en c#

;na interfa= es un tipo #e referencia similar en cierto mo#o a una clase base abstracta compuesta Inicamente por miembros abstractos. Cuan#o una clase #eriva #e una interfa=, #ebe proporcionar una implementaci>n para to#os los miembros #e la interfa=. ;na clase pue#e implementar varias interfaces aunque solo pue#e #erivar #e una Inica clase base #irecta. *as interfaces se utili=an para #efinir funciones especGficas para las clases que no tienen necesariamente una relaci>n #e i#enti#a#. Por ejemplo, cualquier clase o estructura que ten'a que Babilitar el c>#i'o #e cliente para #eterminar si #os objetos #e un tipo son equivalentes Ecualquiera que sea la forma en que el tipo #efina la equivalenciaF, pue#e implementar la interfa= C quatableV[1W. C quatableZ!Y no implica el mismo tipo #e relaci>n #e i#enti#a# que e7iste entre una clase base y una clase #eriva#a Epor ejemplo, <ammal es AnimalF. *as interfaces #escriben un 'rupo #e funcionali#a#es relaciona#as que pue#en pertenecer a cualquier elemento class o struct. *as interfaces pue#en estar compuestas #e mHto#os, propie#a#es, eventos, in#i=a#ores o cualquier combinaci>n #e estos cuatro tipos #e miembros. ;na interfa= no pue#e contener campos. *os miembros #e interfa= son autom.ticamente pIblicos. Cuan#o se #ice que una clase o estructura Bere#a una interfa=, si'nifica que la clase o la estructura proporciona una implementaci>n para to#os los miembros que #efine la interfa=. *a propia interfa= no proporciona nin'una funcionali#a# que una clase o estructura pue#a Bere#ar #e la manera en que se pue#e Bere#ar la funcionali#a# #e una clase base. Sin embar'o, si una clase base implementa una interfa=, la clase #eriva#a Bere#a esta implementaci>n. Al i'ual que las clases se pue#en Bere#ar #e una clase base o estructura, las clases y estructuras se pue#en Bere#ar #e interfaces, con #os e7cepciones1

;na clase o estructura pue#e Bere#ar m.s #e una interfa=. Cuan#o una clase o la estructura Bere#a una interfa=, Bere#a s>lo los nombres #e mHto#o y las firmas, ya que la propia interfa= no contiene nin'una implementaci>n. Por ejemplo1

Sentenci! dele !te

*a #eclaraci>n #e un tipo #ele'a#o es similar a una firma #e mHto#o. !iene un valor #evuelto y un nImero cualquiera #e par.metros #e cualquier tipo1 public #ele'ate voi# !est&ele'ateEstrin' messa'eFM public #ele'ate int !est&ele'ateE<y!ype m, lon' numFM *os #ele'a#os son la base #e los eventos. Se pue#en crear instancias #e un #ele'a#o asoci.n#olo a un mHto#o con nombre o an>nimo. Para obtener m.s informaci>n, vea <Hto#os con nombre y <Hto#os an>nimos. Para crear instancias #el #ele'a#o #ebe utili=arse un mHto#o o una e7presi>n lamb#a que ten'a un tipo #e valor #evuelto y par.metros #e entra#a compatibles. Para obtener m.s informaci>n sobre el 'ra#o #e variaci>n permiti#a en la firma #e mHto#o, vea Covarian=a y contravarian=a en los #ele'a#os. Para el uso con mHto#os an>nimos, el #ele'a#o y el c>#i'o que se van a asociar se #eclaran juntos. n esta secci>n se #escriben las #os formas #e crear instancias #e #ele'a#os.

21

2!n *! e .nte r!ted A*ery

E2.NA, pronuncia#o \lin:]F es un componente #e la plataforma <icrosoft .N ! que a're'a capaci#a#es #e consulta a #atos #e manera nativa a los len'uajes .N !. *CN6 e7tien#e el len'uaje a travHs #e las llama#as e"presiones de consulta, que son pareci#as a las sentencias S6* y pue#en ser usa#as para e7traer y procesar convenientemente #atos #e arrays, clases enumerables, #ocumentos K<*, bases #e #atos relacionales y fuentes #e terceros. *CN6 fue lan=a#o como un componente principal #e .N ! 9rame%or: 3.+ *os opera#ores soporta#os por la APC son1 select, %Bere, select<any, SumL<inL<a7LAvera'e, A''re'ate, join,'roup5oin. jemplo1 var results Q from c in SomeCollection %Bere c.SomeProperty Z 14 select ne% Pc.SomeProperty, c.0tBerPropertyRM

ASP.NET
Estructura de archivos de configuracin de ASP.NET (secciones y controladores de seccin)

.oda la in!ormaci,n de con!i uraci,n de 2&3.4+. reside en los arc-i(os .con!i ./n arc-i(o 5ac-ine.con!i y un arc-i(o 6eb.con!i raz ubicados en una carpeta del sistema de .4+. 7rame8or9 proporcionan los (alores predeterminados de todos los sitios 8eb que se ejecutan en un ser(idor.3ara cada sitio 8eb, un arc-i(o 6eb.con!i ubicado en la carpeta raz del sitio proporciona (alores de reemplazo espec!icos del sitio.3ueden -aber arc-i(os 6eb.con!i adicionales en las subcarpetas de un sitio 8eb para proporcionar los (alores de reemplazo que se aplican espec!icamente a esas carpetas de ese sitio. ;n arcBivo .confi' contiene K<* que tiene un elemento confi'uration como no#o raG=.*a informaci>n inclui#a en este elemento se a'rupa en #os .reas principales1 el .rea #e #eclaraci>n #e los controla#ores #e secciones #e confi'uraci>n y el .rea #e valores #e las secciones #e confi'uraci>n. ;n controla#or #e secci>n es una clase #e .N ! 9rame%or: que implementa la interfa= Confi'urationSection. l .rea #e #eclaraci>n i#entifica el espacio #e nombres y el nombre #e ca#a clase #e controla#or #e secci>n.*os controla#ores #e secciones se utili=an para leer y establecer los valores que pertenecen a una secci>n. n el si'uiente ejemplo, se muestra una vista simplifica#a #e la estructura K<* #e un arcBivo 8eb.confi'. @con8igurationA @+JJ Con8iguration sectionJ&andler declaration area# JJA @con8ig%ectionsA @section name=)section3) type=)section3*andler) 6A @section name=)section5) type=)section5*andler) 6A @6con8ig%ectionsA @+JJ Con8iguration section settings area# JJA @section3A @s3%etting3 attribute3=)attr3) 6A @6section3A @section5A @s5%etting3 attribute3=)attr3) 6A @6section5A @system# ebA @aut&entication mode=)'indo s) 6A @6system# ebA @6con8igurationA +n un arc-i(o 6eb.con!i , las secciones pueden aparecer en el rea de con!i uraci,n no declarada en el rea de declaraci,n si se declaran en un arc-i(o .con!i ubicado en un ni(el superior de la jerarqua de con!i uraci,n.3or ejemplo, la secci,n system.8eb se declara en el arc-i(o 5ac-ine.con!i .3or consi uiente, no es necesario declararla en arc-i(os 6eb.con!i indi(iduales de cada sitio.&i se declara una secci,n en el arc-i(o 6eb.con!i ubicado en la carpeta raz de un sitio 8eb, se pueden incluir los (alores de esa secci,n sin incluirlos en los arc-i(os 6eb.con!i ubicados en las subcarpetas.

22

Web.con/i es el arcBivo principal #e opciones #e confi'uraci>n para una aplicaci>n %eb en ASP.N !. l arcBivo es un #ocumento K<* que #efine informaci>n #e confi'uraci>n concerniente a la aplicaci>n %eb. l arcBivo %eb.confi' contiene informaci>n que controla la car'a #e mo#ulos, confi'uraciones #e se'uri#a#, confi'uraciones #el esta#o #e la sesi>n, opciones #e compilaci>n y el len'uaje #e la aplicaci>n. *os arcBivos %eb.confi' pue#en contener tambiHn objetos especGficos tales como ca#enas #e cone7i>n a la base #e #atos.

jemplo1 Utilizaremos el fichero web.config para almacenar diferentes valores, principalmente aquellos que pensemos cambiar frecuentemente o aquellos que podra ser til tener siempre a mano por ejemplo para ser cambiados desde cualquier lugar sin necesidad de tener Microsoft Visual Studio. Una vez preparado el web.config, utilizaremos el fichero global.asax para leer esta configuracin al arrancar la aplicacin y una clase con variables est ticas para almacenarla y poder leerla desde nuestro cdigo. !n primer lugar, crearemos la seccin appSettings en el fichero de configuracin web.config. "a crearemos dentro del nivel configuration pero fuera del nivel system.web tal y como os muestro a continuacin. Cmo preparar el fichero web.config? !n primer lugar, crearemos la seccin appSettings en el fichero de configuracin web.config. "a crearemos dentro del nivel configuration pero fuera del nivel system.web tal y como os muestro a continuacin. @con8igurationA @system# ebA ### @6system# ebA <appSettings> <add key="CADENA_CONEXION" value="Pr vider=XXX!Data S ur"e=XXX!#ser Id=XXX!Pass$ rd=XXX!data%ase=XXX!"&> <add key="N#'E(O_NO)ICIAS_PO()ADA" value="*+"&> <add key="ADSENSE_AC)I,ADO" value="-alse"&> <&appSettings> @6con8igurationA #omo pod$is ver en el ejemplo, dentro de la seccin que acabamos de crear, introduciremos la clave y valor %la clave pod$is elegirla a vuestro gusto& de las tres variables que bamos a manejar desde el web.config, tal y como habamos comentado anteriormente. Cmo leer esta configuracin desde la aplicacin web? 'ara almacenar la informacin, vamos a crear una clase est tica con un m$todo Init que se encargar de inicializar las variables y que slo ser llamado una vez, al arrancar la aplicacin. 'or si acaso, almacenaremos los datos en variables privadas y crearemos slamente las propiedades et, de esta forma evitaremos que se pueda modificar directamente o por un descuido el valor de estas variables, ya que slo podr n ser modificadas a trav$s del m$todo Init. !l constructor privado sirve para impedir que puedan crearse objetos de esta clase, ya que nicamente nos interesa como clase est tica. public class C n-igura"i n { private static string mKcadenaCone2ion = )); private static int mKnumero,oticias1ortada = 4; private static bool mKadsense7ctivado = 8alse; private C n-igura"i n() { } public static Init(string cadenaCone2ion, numero,oticias1ortada, adsense7ctivado) { mKcadenaCone2ion = cadenaCone2ion;

23

mKnumero,oticias1ortada = numero,oticias1ortada; mKadsense7ctivado = adsense7ctivado; } public string CadenaCone2ion { get { return mKcadenaCone2ion;} } public int ,umero,oticias1ortada { get { return mKnumero,oticias1ortada;} } public bool 7dsense7ctivado { get { return mKadsense7ctivado;} } } Una vez hecho esto, slo nos queda leer la configuracin. 'ara ello utilizaremos el m$todo !pplication"Start del fichero global.asax, ya que se ejecuta slamente una vez, al iniciarse la aplicacin. public class /lobal ; %ystem#'eb#*ttp7pplication { public /lobal() {} ### protected void Appli"ati n_Start(!b"ect sender, Event7rgs e) { string cadenaCone2ion = Syste./C n-igurati n/C n-igurati n'anager/AppSettings<)C7DE,7KC!,E9I!,)=; int numero,oticias1ortada = C nvert/) Int01(%ystem#Con8iguration#Con8iguration-anager#7pp%ettings<),H-ER!K,!$ICI7%K1!R$7D7)= ); C nvert/) 2 bool adsense7ctivado = lean(%ystem#Con8iguration#Con8iguration-anager#7pp%ettings<)7D%E,%EK7C$I07D!)=); C n-igura"i n/Init(cadenaCone2ion, numero,oticias1ortada, adsense7ctivado); } ### } 'ara leer uno de los valores de configuracin, utilizaremos la sentencia System.Configuration.ConfigurationManager.!ppSettings ()clave)*, donde clave es la clave que habamos escogido anteriormente. +ay que tener en cuenta que la sentencia anterior slo nos dar los valores como strings, tal y como aparecen en el fichero web.config. 'or lo tanto, para leer valores enteros o booleanos, tendremos que convertir ese string al tipo de dato correspondiente igual que en el ejemplo.

l arcBivo /lobal#asa2 es opcional y nos permite manejar eventos #e Aplicaci>n y #e Session en nuestra aplicaci>n ASP.NET. l arcBivo /lobal#asa2 resi#e en el #irectorio raG= #e una aplicaci>n #e ASP.NET. ste arcBivo se compila en tiempo #e ejecuci>n, no es accesible por ;(* y #ebe ubicarse en el #irectorio raG= #e la soluci>n. Te)pl!te Blob!l.!s!=:

@LM 7pplication (anguage=)C>) LA @script runat=)server)A void 7pplicationK%tart(ob"ect sender, Event7rgs e) {66 Codigo ?ue se e"ectura cuando inicia la aplicacion } void 7pplicationKEnd(ob"ect sender, Event7rgs e) { 66 Codigo ?ue se e"ectura cuando 8inaliEa la aplicacion } void 7pplicationKError(ob"ect sender, Event7rgs e) { 66 Codigo ?ue se e"ectura cuando ocurre algun error en la aplicacion }

24

void %essionK%tart(ob"ect sender, Event7rgs e) { 66 Codigo ?ue se e"ectura cuando se inicia la sesion# } void %essionKEnd(ob"ect sender, Event7rgs e) { 66 Codigo ?ue se e"ectura cuando 8inaliEa la sesion# } @6scriptA l uso cl.sico es el conta#or #e visitas que #ebe sumar por ca#a usuario que in'rese al sitio %eb. l evento que se ejecuta por ca#a in'reso es%essionK%tart. E6e)plo: C4di o en Bob!l.!s!=: Cniciali=amos una variable en 4 al iniciar la aplicaci>n y lue'o por ca#a inicio #e sesi>n la incrementamos y la car'amos a una variable #e sesi>n para po#er acce#er a ella #es#e el resto #e la aplicaci>n.

private int cnt; void 7pplicationK%tart(ob"ect sender, Event7rgs e) { 66 Codigo ?ue se e"ectura cuando inicia la aplicacion cnt = 4; } void %essionK%tart(ob"ect sender, Event7rgs e) { 66 Codigo ?ue se e"ectura cuando se inicia la sesion# %ession<)cv)= = cntNN; } CoO digo de la pagina asp2 a la ?ue llamaremos Contador0isitas#asp2 @LM 1age (anguage=)C>) LA @script runat=)server)A protected void 1ageK(oad(ob"ect sender, Event7rgs e) { Response#'rite(%ession<)cv)=); @6scriptA } @&tml 2mlns=)&ttp;66 # P#org63QQQ62&tml)A @&ead runat=)server)A @titleA@6titleA @6&eadA @bodyA @8orm id=)8orm3) runat=)server)A @divA @6divA @68ormA @6bodyA @6&tmlA

*a ventaja #e manejarlo #e esta forma es que vamos a lo'rar un conta#or #e visitas reales, es #ecir, s>lo sumar. ca#a inicio #e sesi>n en lu'ar #e sumar ca#a solicitu# a la p.'ina. Para probarlo copiamos el arcBivo Contador0isitas#asp2 y /lobal#asa2 al #irectorio virtual crea#o anteriormente en el CCS y lo ejecutamos1 &ttp;66local&ost6-i1rimera7plicacion'eb6Contador0isitas#asp2. Web.con/i

l arcBivo 'eb#con8ig es el arcBivo principal #e confi'uraciones #e to#a aplicaci>n ASP.NET. s un arcBivo C'2 que controla el funcionamiento #el sitio %eb. Control #e se'uri#a#. Cone7iones a bases #e #atos. sta#o #e las sesiones. Control #e errores. Confi'uraciones personali=a#as. Al i'ual que el 'lobal.asa7 #ebe ser coloca#o en la raG= #e la aplicaci>n.

structura b.sica #e un arcBivo eb#con8ig1

@con8igurationA @system# eb6A @app%ettings6A

25

@6con8igurationA A're'amos ^eys a nuestro eb#con8ig para ver c>mo usarlos en nuestro sitio. Por ejemplo, si queremos controlar que el conta#or #e visitas vaya a estar activo o no a're'amos una :ey llama#a *abilitarContador0isitas y lo seteamos como ver#a#ero. Nuestras ^eys EClavesF vamos a a're'arlos en el ta'@app%ettingsA

@app%ettingsA @add .ey=)*abilitarContador0isitas) value=)true) 6A @6app%ettingsA <o#ificamos el evento %essionK%tart #el global#asa2 para pre'untar el esta#o #e la :ey y controlar el comportamiento #el conta#or #e visitas. Con8iguration-anager#7pp%ettings#/et()*abilitarContador0isitas)) ; Co_#i'o #el evento %essionK%tart

void %essionK%tart(ob"ect sender, Event7rgs e) { 66 Codigo ?ue se e"ectura cuando se inicia la sesion# i8 (Convert#$oGoolean(Con8iguration-anager#7pp%ettings#/et()*abilitarContador0isitas)))) { %ession<)cv)= = cntNN;

} *ue'o copiamos al #irectorio virtual los arcBivos mo#ifica#os y veremos que el conta#or #e visitas siempre nos marcara C (0. <.s a#elante usaremos el eb#con8ig para establecer nuestra cone7i>n con #atos.

B*!rd!do de in/or)!ci4n de p! in!s (eb.


<ucBas veces necesitamos utili=ar par.metros entre #istintos mHto#os #e un mismo formulario %eb, o incluso entre formularios #istintos. ;na forma #in.mica #e reali=ar este intercambio #e #atos es la utili=aci>n #el $ie%State y #el espacio #e sesi>n. Antes #e embarcarnos a almacenar #atos y #atos en estos #os espacios #e memoria, Bay que #ejar claras #os cosas1

+l :ie8&tate se intercambia continuamente entre cliente y ser(idor, por lo que es aconsejable no sobrecar arlo. 2l aumentar el :ie8&tate, aumentar el tama;o de la p ina, y por consi uiente, el tr!ico de datos y la (elocidad de car a de la misma. La sesi,n se almacena en ser(idor, por lo que si nuestro sitio 8eb posee una car a de datos moderada < alta, el rendimiento del mismo se (er penalizado. 4ue(amente, es aconsejable utilizar con cautela este espacio de memoria. !enien#o claros estos #os conceptos, utili=aremos el $ie%State para almacenar #atos locales E#e una misma p.'inaF y la sesi>n para pasar par.metros entre #istintas p.'inas sin Bacer uso #e la 6ueryStrin'. Para los profanos en la materia, e7plicaremos que la 6ueryStrin' es la colecci>n #e par.metros que pue#en, opcionalmente, acompa?ar a la #irecci>n #e la p.'ina. `stos par.metros ofrecen informaci>n #irectamente recopilable por nuestro formulario %eb, pero cuenta con la #esventaja #e que es visible para el usuario. ;n ejemplo #e 6ueryStrin' serGa, por ejemplo, la si'uiente1

2$

Bttp1LL#ani'arcia.or'LDt! Es>lFser0er n ella se est. in#ican#o que la variable ata'b cuenta con el valor asqlNserverb. n nuestra aplicaci>n, po#rGamos reco'er el valor #e esa variable #e la si'uiente forma1

string recurso = (string)Re?uest#Ruery%tring#/et(S?uot;tagS?uot;);

n este momento, la variable recurso almacenarGa el valor asqlNserverb, valor que po#rGamos usar para reali=ar una consulta a base #e #atos. !ambiHn po#emos insertar m.s #e un valor en la 6;eryStrin', concatenan#o los variables en la forma1 Bttp1LL#ani'arcia.or'LDpE2G4Hpre0ie(Etr*e AquG po#rGamos acce#er a #os variables1 apa y apre#ie$a. &ejan#o a un la#o el funcionamiento #e la 6ueryStrin', si lo que realmente quisiHramos es ocultar esta informaci>n, po#remos Bacer uso #e la sesi>n para recuperar los valores entre #istintas p.'inas.

ViewState
l objetivo #e almacenar #atos en el $ie%State es el #e mantener el esta#o #e una variable en la p.'ina #e forma permanente, a mo#o #e variable 'lobal, entre #istintas llama#as a servi#or. Para acce#er a la variable #entro #el $ie%State, reali=arGamos un acceso #e la si'uiente manera1

66 7lmacenar un valor 0ie %tate<S?uot;variableEnteraS?uot;= = P; 66 Recuperar un valor int entero = (int)0ie %tate<S?uot;variableEnteraS?uot;=;

Para simplificar el acceso, es aconsejable encapsularlo #entro #e una property, #e la si'uiente manera1

private int entero { get { return (int)0ie %tate<S?uot;variableEnteraS?uot;=; } set { 0ie %tate<S?uot;variableEnteraS?uot;= = value; }

2%

&e este mo#o, po#remos reali=ar asi'naciones y recuperaciones #e forma completamente natural1

entero = P; int otroEntero = entero;

Hay que comentar, no obstante, el requisito in#ispensable para almacenar un #ato en el $ie%State1 el tipo #el objeto a almacenar #ebe poseer la propie#a# %Seriali&able()' , es #ecir, Ba #e po#er \comprimirse] como una ca#ena #e te7to. <ucBos #e los tipos preestableci#os soportan la seriali=aci>n, pero en el caso #e que creemos una nueva clase que queramos seriali=ar, #eber. #eclararse #el si'uiente mo#o1

<%erialiEable()= public class miClase { 66 Contenido de la clase }

Session
0tra forma #e intercambiar #atos, pero esta ve= entre #istintos formularios Elo cual no impi#e que tambiHn permita el acceso #es#e la propia p.'ina que crea la variableF es el uso #e las variables #e sesi>n. *a forma #e utili=ar la sesi>n es la misma que la #el $ie%State1

66 7lmacenar un valor %ession<S?uot;variableEnteraS?uot;= = P; 66 Recuperar un valor int entero = (int)%ession<S?uot;variableEnteraS?uot;=;

Nuevamente, encapsulan#o la funcionali#a# #entro #e una property, 'anaremos en clari#a#1

2'

private int entero { get { return (int)%ession<S?uot;variableEnteraS?uot;=; } set { %ession<S?uot;variableEnteraS?uot;= = value; } }

AsG, un uso pr.ctico #e la sesi>n serGa la #e obtener el C& #e un elemento selecciona#o en un 'ri#, almacenarlo en sesi>n y re#iri'ir a una p.'ina en la que se tratar. ese mismo elemento. Para ello, se recuperar. la variable #e sesi>n y posteriormente se eliminar. Elo cual es muy aconsejable, pero no obli'atorio, ya que po#emos mantener en sesi>n, por ejemplo, el i#entifica#or #el usuario que est. lo'a#o en la aplicaci>n, y acce#er contGnuamente a esta variable para comprobar, por ejemplo, permisosF.

PAGINA 1

int idHsuario; idHsuario = D7!#ConsultarHsuario(login, pass ord); %ession<S?uot;idHsuarioS?uot;= = idHsuario; 66 Redireccionamos Response#Redirect(S?uot;1agina5#asp2S?uot;);
%

PAGINA 2
66 1roperty ?ue encapsula la variable almacenada en el 0ie %tate private int idHsuario { get { return (int)0ie %tate<S?uot;variableEnteraS?uot;=; } set { 0ie %tate<S?uot;variableEnteraS?uot;= = value; }

2)

} 66 ### 66 Carga de la pTgina protected void 1ageK(oad(ob"ect sender, Event7rgs e) { 66 %i es la carga inicial### i8(+Is1ostGac.) { 66 Comprobamos ?ue la variable de sesiFn UidHsuarioU e2iste i8(%ession<S?uot;idHsuarioS?uot;= += null) { 66 1asamos el ID de usuario al 0ie %tate, ?ue permanecerT en la pTgina local idHsuario = (int)%ession<S?uot;idHsuarioS?uot;=; 66 Eliminamos el ID de usuario de sesiFn %ession<S?uot;idHsuarioS?uot;= = null; } } }

2!s di/erenci!s )Is i)port!ntes entre Session y 8ie(St!te en ASP.NET. l 8ie(St!te es m.s limita#o y es para informaci>n sencilla. Cncluso te pue#es encontrar que almacenas informaci>n que se 'uar#a o actuali=a a travHs #e otros procesos y que no se refresca correctamente. Creo que es #ebi#o a que el $ie%State viaja #el cliente al servi#or, se procesa y vuelve, y si no e7iste un PostAac: por me#io, por mucBo que actualices la informaci>n no se manten#r.n los cambios, ya que la pr>7ima ve= que se 'enere un PostAac: la informaci>n se reiniciar. con la que tenGa 'uar#a#a en la parte #el Cliente. *a Session suele utili=arse para compartir informaci>n entre p.'inas, #e m.s enver'a#ura y con procesos m.s complejos.

3*

Session Compartir informaci>n entre #iferentes p.'inas Pue#e almacenar m.s informaci>n *a informaci>n se 'uar#a en el Servi#or

8ie(St!te S>lo sirve para compartir informaci>n #entro #e 1 s>la p.'ina, aunque Ba'as PostAac:s *a informaci>n a almacenar es m.s limita#a *a informaci>n creo que se 'uar#a seriali=a#a en el Cliente cNod

Brid8ie( ,&ystem.6eb./=.6eb"ontrols-

<uestra los valores #e un ori'en #e #atos en una tabla #on#e ca#a columna representa un campo y ca#a fila representa un re'istro. l control "ri#$ie% permite seleccionar, or#enar y mo#ificar estos elementos. l control "ri#$ie% es el sucesor #el control &ata"ri#. Al i'ual que el control &ata"ri#, el control "ri#$ie% se #ise?> para mostrar los #atos en una tabla H!<*. Cuan#o se enla=an a un ori'en #e #atos, los controles &ata"ri# y "ri#$ie% muestran ca#a uno una fila #e un objeto &ataSource como una fila en una tabla #e resulta#os. !anto el control &ata"ri# como el control "ri#$ie% se #erivan #e la clase 8ebControl. Aunque tiene un mo#elo #e objetos similar al #el control &ata"ri#, el control "ri#$ie% tambiHn #ispone #e una serie #e nuevas caracterGsticas y tiene ciertas ventajas sobre el control &ata"ri#, entre las que se incluyen1

9unciones en tiempo #e #ise?o m.s amplias. 9unciones #e enlace al ori'en #e #atos mejora#as. Control autom.tico #e las operaciones #e or#enaci>n, pa'inaci>n, actuali=aci>n y eliminaci>n. !ipos #e columna a#icionales y operaciones #e columna en tiempo #e #ise?o. ;na interfa= #e usuario #e buscapersonas personali=a#o con la propie#a# Pa'er!emplate.

ntre las #iferencias entre el control "ri#$ie% y el control &ata"ri# se incluyen1


&iferente compatibili#a# con la pa'inaci>n personali=a#a. <o#elos #e evento #iferentes.

0r#enar, pa'inar y e#itar en conte7to los #atos requiere co#ificaci>n a#icional cuan#o se utili=a el control &ata"ri#. l control "ri#$ie% permite a're'ar funciones #e or#enaci>n, pa'inaci>n y e#ici>n sin escribir c>#i'o al'uno. n su lu'ar, pue#e automati=ar estas tareas junto con otras tareas comunes, como enla=ar a #atos un ori'en #e #atos, #efinien#o las propie#a#es #el control. Si est. trabajan#o en un #ise?a#or, como <icrosoft $isual Stu#io, pue#e aprovecBar las caracterGsticas #e #ise?o inte'ra#as en el control "ri#$ie%. l control "ri#$ie% es compatible a#em.s con un panel #e etiquetas inteli'entes que proporciona una interfa= conveniente para reali=ar tareas comunes, como #efinir propie#a#es e iniciar la e#ici>n #e plantillas.
31

&epe!ter

"!t! #!se Access


A"%.NET

A"%.NET es un conjunto #e componentes #el soft%are que pue#en ser usa#os por los pro'rama#ores para acce#er a #atos y a servicios #e #atos. s una parte #e la biblioteca #e clases base que est.n inclui#as en el <icrosoft .N ! 9rame%or:. s comInmente usa#o por los pro'rama#ores para acce#er y para mo#ificar los #atos almacena#os en un Sistema "estor #e Aases #e &atos (elacionales, aunque tambiHn pue#e ser usa#o para acce#er a #atos en fuentes no relacionales. A&0.N ! es a veces consi#era#o como una evoluci>n #e la tecnolo'Ga ActiveK &ata 0bjects EA&0F, pero fue cambia#o tan e7tensivamente que pue#e ser concebi#o como un pro#ucto enteramente nuevo.

Ar>*itect*r! A&0.N ! consiste en #os partes primarias1 "!t! pro0ider stas clases proporcionan el acceso a una fuente #e #atos, como <icrosoft S6* Server y 0racle. Ca#a fuente #e #atos tiene su propio conjunto #e objetos #el provee#or, pero ca#a uno tienen un conjunto comIn #e clases #e utili#a#1 Connection1 Proporciona una cone7i>n usa#a para comunicarse con la fuente #e #atos. !ambiHn actIa como Abstract 9actory para los objetos comman#. Comman#1 ;sa#o para reali=ar al'una acci>n en la fuente #e #atos, como lectura, actuali=aci>n, o borra#o #e #atos relacionales. Parameter1 &escribe un simple par.metro para un command. ;n ejemplo comIn es un par.metro para ser usa#o en un proce#imiento almacena#o. &ataA#apter1 OPuenteO utili=a#o para transferir #ata entre una fuente #e #atos y un objeto &ataSet Ever abajoF. &ata(ea#er1 s una clase usa#a para procesar eficientemente una lista 'ran#e #e resulta#os, un re'istro a la ve=.

"!t!Sets

32

*os objetos &ataSets, es un 'rupo #e clases que #escriben una simple base #e #atos relacional en memoria, fueron la estrella #el sBo% en el lan=amiento inicial E1.4F #el <icrosoft .N ! 9rame%or:. *as clases forman una jerarquGa #e contenci>n1 ;n objeto "!t!Set representa un esquema Eo una base #e #atos entera o un subconjunto #e unaF. Pue#e contener las tablas y las relaciones entre esas tablas. o ;n objeto "!t!T!ble representa una sola tabla en la base #e #atos. !iene un nombre, filas, y columnas. ;n objeto "!t!8ie( Ose sienta sobreO un &ata!able y or#ena los #atos Ecomo una cl.usula Oor#er byO #e S6*F y, si se activa un filtro, filtra los re'istros Ecomo una cl.usula O%BereO #el S6*F. Para facilitar estas operaciones se usa un Gn#ice en memoria. !o#as las &ata!ables tienen un filtro por #efecto, mientras que pue#en ser #efini#os cualquier nImero #e &ata$ie%s a#icionales, re#ucien#o la interacci>n con la base #e #atos subyacente y mejoran#o asG el #esempe?o. ;n "!t!Col*)n representa una columna #e la tabla, incluyen#o su nombre y tipo. ;n objeto "!t!&o( representa una sola fila en la tabla, y permite leer y actuali=ar los valores en esa fila, asG como la recuperaci>n #e cualquier fila que estH relaciona#a con ella a travHs #e una relaci>n #e clave primaria N clave e7tranjera. ;n "!t!&o(8ie( representa una sola fila #e un &ata$ie%, la #iferencia entre un &ata(o% y el &ata(o%$ie% es importante cuan#o se est. interactuan#o sobre un resultset.

o o

;n "!t!&el!tion es una relaci>n entre las tablas, tales como una relaci>n #e clave primaria N clave ajena. sto es Itil para permitir la funcionali#a# #el &ata(o% #e recuperar filas relaciona#as. ;n Constr!int #escribe una propie#a# #e la base #e #atos que se #ebe cumplir, como que los valores en una columna #e clave primaria #eben ser Inicos. A me#i#a que los #atos son mo#ifica#os cualquier violaci>n que se presente causar. e7cepciones.

;n &ataSet es llena#o #es#e una base #e #atos por un &ataA#apter cuyas propie#a#es Connection y Comman# que Ban si#o inicia#os. Sin embar'o, un &ataSet pue#e 'uar#ar su conteni#o a K<* Eopcionalmente con un esquema KS&F, o llenarse a sG mismo #es#e un K<*, Bacien#o esto e7cepcionalmente Itil para los servicios %eb, computaci>n #istribui#a, y aplicaciones ocasionalmente conecta#as #esconecta#os. *os objetos &ataSets, es un 'rupo #e clases que #escriben una simple base #e #atos relacional en memoria, fueron la estrella #el sBo% en el lan=amiento inicial E1.4F #el <icrosoft .N ! 9rame%or:. *as clases forman una jerarquGa #e contenci>n1 ;n objeto "!t!Set representa un esquema Eo una base #e #atos entera o un subconjunto #e unaF. Pue#e contener las tablas y las relaciones entre esas tablas. o ;n objeto "!t!T!ble representa una sola tabla en la base #e #atos. !iene un nombre, filas, y columnas. ;n objeto "!t!8ie( Ose sienta sobreO un &ata!able y or#ena los #atos Ecomo una cl.usula Oor#er byO #e S6*F y, si se activa un filtro, filtra los re'istros Ecomo una cl.usula O%BereO #el S6*F. Para facilitar estas operaciones se usa un Gn#ice en memoria. !o#as las &ata!ables tienen un filtro por #efecto, mientras que pue#en ser #efini#os cualquier nImero #e &ata$ie%s a#icionales, re#ucien#o la interacci>n con la base #e #atos subyacente y mejoran#o asG el #esempe?o. ;n "!t!Col*)n representa una columna #e la tabla, incluyen#o su nombre y tipo. ;n objeto "!t!&o( representa una sola fila en la tabla, y permite leer y actuali=ar los valores en esa fila, asG como la recuperaci>n #e cualquier fila que estH relaciona#a con ella a travHs #e una relaci>n #e clave primaria N clave e7tranjera. ;n "!t!&o(8ie( representa una sola fila #e un &ata$ie%, la #iferencia entre un &ata(o% y el &ata(o%$ie% es importante cuan#o se est. interactuan#o sobre un resultset.

;n "!t!&el!tion es una relaci>n entre las tablas, tales como una relaci>n #e clave primaria N clave ajena. sto es Itil para permitir la funcionali#a# #el &ata(o% #e recuperar filas relaciona#as.

33

;n Constr!int #escribe una propie#a# #e la base #e #atos que se #ebe cumplir, como que los valores en una columna #e clave primaria #eben ser Inicos. A me#i#a que los #atos son mo#ifica#os cualquier violaci>n que se presente causar. e7cepciones.

;n &ataSet es llena#o #es#e una base #e #atos por un &ataA#apter cuyas propie#a#es Connection y Comman# que Ban si#o inicia#os. Sin embar'o, un &ataSet pue#e 'uar#ar su conteni#o a K<* Eopcionalmente con un esquema KS&F, o llenarse a sG mismo #es#e un K<*, Bacien#o esto e7cepcionalmente Itil para los servicios %eb, computaci>n #istribui#a, y aplicaciones ocasionalmente conecta#as #esconecta#os. A"%.NET Entity +r!)e(or9 l A"%.NET Entity +r!)e(or9 es un conjunto #e APCs #e acceso a #atos para el <icrosoft .N ! 9rame%or:, apuntan#o a la versi>n #e A&0.N ! que se incluye con el .N ! 9rame%or: 3.+. 9ue lan=a#o como actuali=aci>n separa#a junto con el Service Pac: 1 para el .N ! 9rame%or:, #espuHs #el lan=amiento #e tanto el .N ! 9rame%or: 3.+ y el $isual Stu#io 244/. ;na nueva versi>n #el ntity 9rame%or: Ev ).4F ser. libera#a junto al $isual Stu#io 2414 y el .N ! 9rame%or: ).4. ;na enti#a# #el ntity 9rame%or: es un objeto que tiene una clave representan#o la clave primaria #e una enti#a# l>'ica #e #atastore. ;n mo#elo conceptual ntity &ata <o#el Emo#elo nti#a#N(elaci>nF es mapea#o a un mo#elo #e esquema #e #atastore. ;san#o el ntity &ata <o#el, el 9rame%or: permite que los #atos sean trata#os como enti#a#es in#epen#ientemente #e sus representaciones #el #atastore subyacente. l ntity S6* es un len'uaje similar al S6* para consultar el ntity &ata <o#el Een ve= #el #atastore subyacenteF. Similarmente, las e7tensiones #el *inq, *inqNtoN ntities, proporcionan consultas tipea#as en el ntity &ata <o#el. *as consultas ntity S6* y *inqNtoN ntities son converti#as internamente en un Canonical 6uery !ree que entonces es converti#o en una consulta comprensible al #atastore subyacente Eej. en S6* en el caso #e una base #e #atos relacionalF. *as enti#a#es pue#en utili=ar sus relaciones, y sus cambios envia#os #e re'reso al #atastore.

Entity +r!)eWor9

ntity 9rame%or: es una 0(< #e <icrosoft que permite superponer varias capas #e abstracci>n sobre un almacHn #e #atos #e cualquier Vo casi to#osW los motores #e Aase #e #atos actuales, estas capas #e abstracci>n nos permiten a los #esarrolla#ores po#er trabajar sobre un )odelo concept*!l #e una base #e #atos relacional. sta abstracci>n nos permite a los #esarrolla#ores po#er trabajar sobre un entorno #e #esarrollo mas controla#o, y unifica#o, en el senti#o que aBora nuestras consultas po#r.n ser compila#asUUe es #ecir 'racias a *inq po#remos escribir nuestras consultas en un len'uaje .N ! y saber si 'eneran al'In tipo #e error en tiempo #e compilaci>n, previnien#o #e esta manera mucBas #e las e7cepciones que tenGamos a la Bora #e escribir consultas en !NSql en Strin's #e .N !. $entaja a#icional #e manejar *inq es que es est.n#ar y unifica#o, es #ecire. ya no tenemos que apren#ernos sentencias raras #e bases para reali=ar consultas. Ar>*itect*r! de Entity /r!)e(or9 Ja se Ba #icBo que ntity 9rame%or: superpone varias capas #e abstracci>n sobre un almacHn #e #atos, peroe cCuales son esas capasd

34

Como se pue#e apreciar en la ima'en anterior se tiene en la parte inferior esta nuestra base #e #atos y sobre esta se encuentra la capa #e provee#ores #e 9, en esta capa se encuentra el provee#or especifico para el motor #e Aase #e #atos en el que tenemos nuestra base #e #atos, sobre esta capa encontramos el Entity "!t! 'odel; este sera nuestro mo#elo conceptual y se #ivi#e en otras subcapas que presento a continuaci>n en otra #iapositiva #e aquella conferencia1

Si'uen#o con las capas #e la arquitectura #e 9 nos encontramos con Entity Client, este es nuestro provee#or especifico para consumir mo#elos conceptuales #e ntity 9rame%or:. Entity SA2 es el len'uaje #e consultas #e ntity 9rame%or:. %b6ect Ser0ices proporciona la materiali=aci>n #e nuestras consultas en enti#a#es #el #ominio. F Co)ponente de Entity "!t! 'odel Como ya sabemos, cuan#o creamos un mo#elo #e ntity 9rame%or: este se crea con la e7tensi>n . &<K. stos ficBeros m#7 se forman a partir #e tres arcBivos K<* llama#os SS&*, CS&* y <S* respectivamente. SS"2, Stora'e ScBema &efinition *an'ua'e, ste arcBivo #escribe la estructura fGsica #e la base #e #atos, incluyen#o la #efinici>n #e las tablas, las vistas, SPbs y relaciones. CS"2; Conseptual ScBema &efinition *an'ua'e, Se encar'a #e #escribir las enti#a#es que #eseamos tener en nuestro mo#elo conceptual Epropie#a#es #e nave'aci>n y asociacionesF 'S2; <appin' ScBema *an'ua'e, &efine como se asocian las enti#a#es #el mo#elo conceptual con las enti#a#es #el mo#elo fGsico. ABora que tenemos un poco mas claro la arquitectura #e #esplie'ue #e ntity 9rame%or: po#emos empe=ar a trabajar con este y no Bacer Ecomo #ecGa mi profesor #e 5A$AF pro'ramar como =ombies. +or)!s de *tili?!ci4n EBttp1LL'ustavoa=cona.blo'spot.com.arL2411L4,LentityNframe%or:N#atabaseNfirst.BtmlDUL2411L4,LentityNframe%or:N#atabaseNfirst.BtmlF Para comen=ar a trabajar con ntity 9rame%or:, po#emos Bacerlo me#iante 3 enfoques #iferentes para crear nuestro mo#elo conceptual.

1. "!t!b!se +irst l mo#elo conceptual se crea a partir #e una base #e #atos e7istente. 35

ste enfoque permite inferir un mo#elo #e clases a partir #el esquema #e una base #e #atos e7istente.

;san#o $isual Stu#io, po#emos a're'ar un Gtem #e proyecto llama#o Entity "!t! 'odel e iniciar un asistente para conectarnos a una base #e #atos, seleccionar los objetos que queremos incluir en el mo#elo Etablas, vistas, store# proce#uresF y 'enerar un arcBivo . ed)= que contiene una representaci>n K<* #e1 l )odelo concept*!l ECS&* f Conceptual ScBema &efinition *an'ua'eF el )odelo de d!tos ESS&* f Store ScBema &efinition *an'ua'eF y el )!peo entre ambos mo#elos E<S* f <appin' Specification *an'ua'eF

l si'uiente 'r.fico muestra un ejemplo #el conteni#o K<* #e un arcBivo .e#m71

s importante enten#er que el )odelo concept*!l ECS&*F no #ebe ser necesariamente i'ual al )odelo de d!tos ESS&*F, y por ello e7iste el )odelo de )!peo E<S*F. A partir #e ese arcBivo .ed)=, se 'enera autom.ticamente Eusan#o plantillas !)F un arcBivo .ed)=.desi ner.cs E.vb en el caso #e $A.N !F que contiene las clases que representan a las enti#a#es #el )odelo concept*!l.

Pue#e observarse que estas clases Bere#an #e Entity%b6ect y tienen varios atributos y propie#a#es #epen#ientes #e Entity+r!)e(or9. !Gpicamente, se crea una clase Eenti#a#F por ca#a tabla #e la base #e #atos, incluyen#o propie#a#es que se mapean a campos y las relaciones entre las tablas son representa#as me#iante propied!des de n!0e !ci4n. A#em.s #e las clases #e enti#a#es se 'enera tambiHn una clase que Bere#a #e %b6ectConte=t y representa el conte7to #e base #e #atos. A travHs #e esta clase ten#remos acceso a las enti#a#es y colecciones #el mo#elo y po#remos reali=ar to#as las operaciones #e lectura y escritura #e #atos #es#e y Bacia la base #e #atos subyacente.

3$

n el si'uiente ejemplo, #oo9storeEntities es la clase 'enera#a por 9 que Bere#a #e %b6ectConte=t1

*ue'o po#emos usarla para acce#er al mo#elo1

JP*edo )odi/ic!r o e=tender l!s cl!ses de entid!des ener!d!s por E+D *as clases 'enera#as en el arcBivo .desi ner son reN'enera#as ca#a ve= que se actuali=a el mo#elo en el arcBivo .ed)=. n consecuencia, no po#emos mo#ificar o a're'ar c>#i'o a esas clases. *a buena noticia es que son clases parciales y po#emos e7ten#erlas en otro arcBivo o bien po#emos usar Berencia. JA*: p!s! si l! b!se de d!tos c!)bi!D Habr. que actuali=ar el mo#elo conceptual. sto pue#e lo'rarse f.cilmente a travHs #el #esi'ner #el e#m71

3%

Se inicia el asistente #e actuali=aci>n en el cual po#emos a're'ar nuevas tablas, vistas o store# proce#ures, refrescar las tablas e7istentes o eliminar otras.

;na ve= finali=a#o el asistente, el arcBivo e#m7 se actuali=a y se reN'eneran las clases #e enti#a#es. *ue'o Babr. que actuali=ar el c>#i'o que Bace referencia a las enti#a#es mo#ifica#as Esi correspon#eF. Concl*si4n l enfoque "!t!b!se +irst nos permite 'enerar r.pi#amente nuestro mo#elo #e clases y mantenerlo sincroni=a#o cuan#o el mo#elo #e #atos cambia. l arcBivo ed)= contiene una #efinici>n K<* #el )odelo concept*!l ECS&*F, el )odelo de d!tos ESS&*F y el )!peo entre ambos. *as clases 'enera#as Bere#an #e Entity%b6ect y se utili=a una clase que Bere#a #e %b6ectConte=t para a#ministrar el mo#elo y reali=ar las operaciones #e persistencia.

3'

2.

Code +irst

ste enfoque est. #isponible a partir #e la versi>n A&0.N ! ntity 9rame%or: ).1 y nos permite crear un mo#elo #e clases P%C% EPlain 0l# C*( 0bjectF a partir #el cual po#emos 'enerar una base #e #atos yLo mapear esas clases a una base #e #atos e7istente. AquG no e7iste un arcBivo ed)= con las #efiniciones K<* #el mo#elo conceptual, el mo#elo #e #atos y el mapeo entre ambos. l mo#elo conceptual est. #efini#o por el conjunto #e clases que Bemos crea#o para representar a las enti#a#es #e nuestro mo#elo #e #ominio. *a i#ea es que nuestras clases P0C0 sean mapea#as #irectamente a la base #e #atos. *a ventaja #e usar clases P%C% es que el mo#elo #e clases es m.s limpio y las clases no tienen #epen#encia con Entity+r!)e(or9 Ecomo suce#e cuan#o las enti#a#es Bere#an #e Entity%b6ect, implementan ciertas interfaces y contienen atributosF. JC4)o se )!pe!n l!s cl!ses P%C% ! l! b!se de d!tosD &e forma pre#etermina#a, se *tili?! *n )!peo por con0enci4n en l* !r de con/i *r!ci4n. s #ecir, si no especificamos el mapeo, se utili=an los nombres #e las clases y sus propie#a#es para 'enerar los nombres #e las tablas y sus campos. ste )!peo por con0enci4n pue#e ser suficiente en nuevos proyectos, #on#e estamos #efinien#o y #ise?an#o el mo#elo conceptual y la base #e #atos #es#e cero. JA*: p!s! si y! ten o *n! b!se de d!tos Kered!d!D Si el esquema #e la base #e #atos Bere#a#a coinci#e con el mo#elo conceptual, entonces el mapeo por convenci>n se'uir. sien#o suficiente y aplicable y to#os felicesU EProbabili#a#1 4.4444441gF *a e7periencia in#ica que si ya tenemos una base #e #atos Bere#a#a, es altamente probable que Baya #iferencias con el mo#elo conceptual utili=a#o en la aplicaci>n. ntonces1 Qu hacemos cuando el esquema de base de datos es diferente al modelo conceptual? Qu tal si quiero especificar restricciones, tipos de datos o validaciones a los campos?

Aien, po#emos resolver estas cuestiones y otras tantas a travHs #e1 1. 2. &ata Annotations <appin' 9luent APC

"!t! Annot!tions stas clases est.n #isponibles en el namespace Syste).Co)ponent'odel."!t!Annot!tions y permiten especificar restricciones o vali#aciones, especificar nombres #e tablas o campos, etc.

3)

Hay #os artGculos interesantes sobre "!t! Annot!tions que recomien#o Een in'lHsF1 Co#e 9irst &ataAnnotations &ata Annotations in tBe ntity 9rame%or: an# Co#e 9irst

'!ppin +l*ent AP. *a se'un#a alternativa que Co#e 9irst ofrece para #efinir el mapeo entre el mo#elo conceptual y la base #e #atos es me#iante 9luent APC. sta APC permite especificar la confi'uraci>n #e mapeo y otras confi'uraciones me#iante c>#i'o.

*os si'uientes enlaces contienen un artGculo interesante con ejemplos sobre Code +irst +l*ent AP. y un vi#eo paso a paso1 9luent APC Samples Co#e 9irst1 <appin' 9luent APC E$i#eoF

JL el conte=to de d!tos de Code +irstD &e forma pre#etermina#a, con el enfoque "!t!b!se +irst y 'odel +irst #isponemos #e una clase %b6ectConte=t #el cual Bere#a el conte7to #e #atos #e nuestra aplicaci>n. Con el enfoque Code +irst tenemos un nuevo conte7to llama#o "bConte=t #el cual #ebe Bere#ar el conte7to #e #atos #e nuestra aplicaci>n.

4*

n el conte7to #e #atos, b.sicamente estamos #efinien#o cu.les son los conjuntos #e enti#a#es que ser.n mapea#os a la base #e #atos. A#icionalmente, po#emos usar iniciali=a#ores #e bases #e #atos, especificar confi'uraciones #e mapeo o interceptar las operaciones #e S!0eCK!n es Eentre otrasF. "bConte=t no es m.s que una versi>n simplifica#a #e %b6ectConte=t, y tambiHn pue#e ser usan#o con los enfoques "!t!b!se +irst y 'odel +irst. JC4)o o c*!ndo se ener! l! b!se de d!tosD Cuan#o se crea una instancia #e "bConte=t, #e forma pre#etermina#a, se utili=a una estrate'ia #e iniciali=aci>n que crea a base #e #atos si no e7iste, opcionalmente se pue#e a're'ar c>#i'o para insertar re'istros #espuHs #e la creaci>n. stas operaciones #e iniciali=aci>n pue#en ser implementa#as usan#o el mHto#o "!t!b!se.Set.niti!li?er. `ste mHto#o toma como par.metro una estrate'ia #e iniciali=aci>n #e base #e #atos. ntity 9rame%or: Co#e 9irst incluye 3 iniciali=a#ores1 1. 2. 3. Create&atabaseCfNot 7ist &ropCreate&atabaseAl%ays &ropCreate&atabaseCf<o#elCBan'es

Po#emos utili=ar estos iniciali=a#ores #e base #e #atos, cuan#o la aplicaci>n se inicia. Por ejemplo, en una aplicaci>n %eb po#rGamos usarlo en el evento Applic!tionMSt!rt #el arcBivo lob!l.!s!=, en una aplicaci>n #e consola po#rGamos incluirlo en el mHto#o '!in #el pro'rama principal.

A#icionalmente, po#emos crear una clase que Bere#a #e al'uno #e estos iniciali=a#ores y sobreescribir el mHto#o Seed para insertar re'istros #espuHs que la base #e #atos es crea#a.

41

*ue'o, usamos esta clase al iniciar la aplicaci>n1

JC4)o ser7! l! inici!li?!ci4n de b!se de d!tos en *n entorno de prod*cci4nD Aueno, es claro que en el entorno #e #esarrollo o pruebas, la iniciali=aci>n #e base #e #atos pue#e ser muy Itil. Pero en un entorno #e pro#ucci>n po#rGa ser un problema. Simplemente po#emos \apa'ar] la iniciali=aci>n #e base #e #atos, pasan#o n*ll como par.metro #el mHto#o Set.niti!li?er1

Concl*si4n Code +irst es el nuevo enfoque soporta#o por ntity 9rame%or:. Permite mapear nuestras clases P0C0 #irectamente a la base #e #atos. &e forma pre#etermina#a, el )!peo es por con0enci4n en lu'ar #e confi'uraci>n. Confi'uraci>n a#icional #e mapeo pue#e especificarse me#iante "!t! Annot!tions o +l*ent AP.. "bConte=t AP. nos permite reali=ar las operaciones #e acceso a #atos.

3. 'odel +irst Se crea el mo#elo conceptual y se 'enera la base #e #atos. *a i#ea aquG es crear primero el mo#elo conceptual y a partir #e este 'enerar la base #e #atos. ;san#o 8is*!l St*dio po#emos arrancar crean#o un arcBivo .ed)= vacGo y utili=amos el #ise?a#or visual para crear nuestras enti#a#es con sus propie#a#es y relaciones con otras enti#a#es. Cuan#o tenemos nuestro mo#elo conceptual completo, po#emos 'enerar los scripts #e S6* para crear el esquema #e base #e #atos.

42

JA*: p!s! si l! b!se de d!tos c!)bi!D n reali#a#, la base #e #atos #ebe cambiar como consecuencia #e un cambio en el mo#elo conceptual. %9 JA*: p!s! si el )odelo concept*!l c!)bi!D Habr. que actuali=ar el mo#elo conceptual #e ntity9rame%or: y 'enerar los scripts S6* #e creaci>n #e la base #e #atos. &esafortuna#amente, los scripts S6* 'enera#os a partir #el mo#elo conceptual son solo scripts #e creaci>n. s #ecir, no son scripts #e cambios o actuali=aci>n #e nuestro esquema #e base #e #atos. n consecuencia, #eberGamos borrar la base #e #atos y volver a crearla. 0bviamente, esto no ser. factible en un entorno #e pro#ucci>n y #eberemos ele'ir otras alternativas. Por ejemplo1 1. 2. 3. Actuali=ar el esquema #e #atos a travHs #e scripts escritos a manos o 'enera#os me#iante una Berramienta #e comparaci>n #e esquema #e #atos. !ambiHn po#rGamos alterar el esquema usan#o el A#ministra#or #e base #e #atos *ue'o #eberGamos, actuali=ar el mo#elo conceptual #e ntity 9rame%or: Ee#m7F y ase'urarnos que el mapeo Bacia la base #e #atos es correcto. 9inalmente, actuali=ar el c>#i'o e7istente en la aplicaci>n.

0jal. que en un futuro, el equipo #e 9 pue#a incorporar un compara#or #e esquemas y 'enerar scripts #e actuali=aci>n. Ya tengo mi modelo conceptual creado, como sigo? Aueno, a partir #e aBora no #ifiere #el enfoque "!t!b!se +irst. Po#emos escribir querys contra el mo#elo conceptual y reali=ar las operaciones #e persistencia necesarias. J2!s cl!ses de entid!des ener!d!s con 'odel +irst son P%C%D &e forma pre#etermina#a N0. *as clases contienen meta#ata y Bere#an #e clases #epen#ientes #e Entity+r!)e(or9. Al i'ual que con "!t!b!se +irst, #isponemos #e una clase que Bere#a #e %b6ectConte=t que nos permite interactuar con el mo#elo. Sin embar'o, es posible tener clases P0C0 a're'an#o un Gtem #e 'eneraci>n #e c>#i'o llama#o1 A"%.NET P%C% Entity Bener!tor. ENE'P2%. 'odelo en b!se de d!tos *o primero que necesitamos como prerequisito es tener una base #e #atos, en mi caso una en S6* Server con la si'uiente estructura1

Cre!ndo n*estro 'odelo concept*!l *o primero es abrir la mejor C& #el mun#o, nuestro $isual Stu#io 2414 . ArcBivo, nuevo, proyecto y seleccionamos un proyecto #el tipo aplicaci>n #e Consola. ABora bien, al'o que se #ebe tener en cuenta antes #e se'uir, es que un mo#elo #e ntity 9rame%or: es n elemento y N0 un tipo #e proyecto, por esto el si'uiente paso sera a're'ar un nuevo elemento a nuestro proyecto #e Consola, Clic: #erecBo, a're'ar, nuevo elemento, en la cate'orGa &ata seleccionamos el tipo A&0.N ! ntity &ata <o#el1 Al pulsar A##, nos sal#r. un asistente #e cone7i>n. n la primera se nos #a la opci>n #e crear un mo#elo conceptual a partir #e un mo#elo #e base #e #atos, y la otra crear un mo#elo vacGo que lue'o po#remos enviar a una base #e #atos, esto es lo que se conoce como 'odel +irst Vno lo cubriremos en esta entra#aW. la tHcnica que usaremos en esta entra#a se conoce como "!t!b!se +irst. n esta ventana especificamos la cone7i>n a la base #e #atos #on#e estar. nuestro mo#elo fGsico, en mi caso que#arGa asG1

43

Pulsamos \o:] y terminamos #e confi'urar la creaci>n #el &<K. Como vemos, el %i=ar# ya nos Ba proporciona#o un nombre para el ntity connection y a#emas no pre'unta si #eseamos incluir el ;suario y la contrase?a #e la cone7i>n la ca#ena #e cone7i>n, po#rGamos Epor se'uri#a#F #ejarla por separa#o en el mismo arcBivo #e confi'uraci>n NC(CP!A&A, pero en este caso a manera #e ejemplo le #iremos que si incluya esta informaci>n y pulsaremos si'uiente. l Si'uiente y ultimo paso es seleccionar que elementos #e nuestro mo#elo fGsico #eseamos traer a nuestro mo#elo conceptual, se nos #an las opciones #e Plurali=ar o sin'ulari=ar estos elementos, por lo 'eneral los trabajo #e mo#o Sin'ular #es#e que est.n en la base #e #atos. 0tra opci>n que nos #a es #e incluir las llaves for.neas en nuestro mo#elo y #ar un nombre al espacio #e nombres #el mo#elo1 ;na ve= pulsamos \finisB] veremos una caracterGstica muy buena #e $isual Stu#io 2414, el Entity 'odel "esi ner con las enti#a#es que se Ban crea#o a partir #e el mo#elo fGsico que tenGamos en la base #e #atos. y a#emas #e este, $isual Stu#io 2414 inte'ra otra fascinante Berramienta que nos facilita el trabajo en proyectos con mucBas enti#a#es, el 'odel #ro(ser, se vera al'o como1 F E=plor!ndo n*estro 'odelo Concept*!l Antes #e continuar seria bueno fijarnos en ciertas cosillas, la primera que po#emos notar es que ntity 9rame%or: nos Ba a're'a#o autom.ticamente un arcBivo #e confi'uraci>n y en su interior nos Ba a're'a#o un Connection Strin' con una forma muy peculiar, al'o como1 a## nameQO 9&emo ntitiesO connectionStrin'QOmeta#ataQres1LLXL<o#el1.cs#lhres1LLXL<o#el1.ss#lh res1LLXL<o#el1.mslMprovi#erQSystem.&ata.SqlClientMprovi#er connection strin'QO#ata sourceQ.M initial catalo'Q 9&emoMuser i#QsaMpass%or#QXXXXMmultipleactiveresultsetsQ!rue Si nos fijamos #eteni#amente vemos que en esta se #efine varios atributos, el primero y muy importante es el #e meta#ata quien es el que #efine #e que se compon#r. nuestro e#m7, por supuesto #e los tres arcBivos K<* #e los que Bablamos en el post anterior ECS&*, SS&* y <S*F, l si'uiente atributo es el provee#or especifico con el que reali=amos esta cone7i>n Een mi caso es el S6*ClientF, el Servi#or #on#e se encuentra la A&, la A&, el usuario y contrase?a, la propie#a# multipleactiveresultsets que nos in#ica si se pue#en asociar varios conjuntos #e resulta#os activos a la cone7i>n asocia#a. y por ultimo tenemos el provi#erName que como ya BabGamos #icBo en el post anterior el provi#er #e ntity 9rame%or: se llama EntityClient. 0tro aspecto importante a resaltar es que se Ba a're'a#o una referencia al ensambla#o Syste)."!t!.Entity. F Cons*)iendo n*estro 'odelo Concept*!l: ABora que tenemos un poco mas claro el porque #e los estra'os que Ba causa#o nuestro mo#elo en la apariencia #e la soluci>n, po#emos empe=ar a picar c>#i'o. n el mHto#o main #e nuestra app a're'aremos una sentencia *sin Eporque es autoNa#ministrable ,etc, etcF y #entro #e este creamos una instancia #e nuestro mo#elo, asG1 class Pro'ram P static voi# <ainEstrin'VW ar'sF P usin' E 9&emo ntities conte7t Q ne% 9&emo ntitiesEFF P R R R FA re !ndo d!tos con Entity +r!)e(or9: Como #ije en el primer post #e esta serie, ntity 9rame%or: nos aBorra el tener que mapear a mano nuestras enti#a#es a enti#a#es #e #ominio, y e7pone autom.ticamente mucBos mHto#os que ayu#an a las operaciones C(;&. Para a're'ar un elemento a la enti#a# Pais, #ebemos crear un objeto #e este tipo, a're'arlo al conte7to y 'uar#ar los cambios, asG1 class Pro'ram P static voi# <ainEstrin'VW ar'sF P usin' E 9&emo ntities conte7t Q ne% 9&emo ntitiesEFF P conte7t.Pais.A##0bjectEne% PaisPNombre Q OColombiaORFM conte7t.SaveCBan'esEFM R R R

44

ntity 9rame%or: #etecta si un campo es Autonumerico, es por esto que N0 es necesario setearle un valor numHrico a la propie#a# C#. ABora bien si quisiHramos a're'ar un objeto HC50 es #ecir, una ciu#a#, po#emos usar las propie#a#es #e nave'aci>n que nos #a ntity 9rame%or: cuan#o #etecta llaves for.neas, asG que serGa cuesti>n #e #efinir un valor a esta propie#a#, asG1 class Pro'ram P static voi# <ainEstrin'VW ar'sF P usin' E 9&emo ntities conte7t Q ne% 9&emo ntitiesEFF P Pais pais Q ne% Pais P Nombre Q OAoliviaO RM Ciu#a# ciu#a# Q ne% Ciu#a#PNombre Q O*a Pa=ORM pais.Ciu#a#.A##Eciu#a#FM conte7t.Pais.A##0bjectEpaisFM conte7t.SaveCBan'esEFM R R R FEli)in!ndo d!tos con Entity +r!)e(or9: Para eliminar un #ato con ntity 9rame%or:, es necesario primero recuperarlo y lue'o si eliminarlo, al'o asG1 class Pro'ram P static voi# <ainEstrin'VW ar'sF P usin' E 9&emo ntities conte7t Q ne% 9&emo ntitiesEFF P Pais pais Q Efrom p in conte7t.Pais %Bere p.Nombre QQ OColombiaO select pF.9irst0r&efaultEFM conte7t.Pais.&elete0bjectEpaisFM conte7t.SaveCBan'esEFM R R n el escenario anterior, eliminamos un objeto \pa#re] que no tenia \Bijos], es un escenario sencillo pero nos sirve para enten#er yLo conocer la sinta7is #e *inq por ejemplo y nos sirve para notar a#emas, que siempre que se realice un cambio, si se #esea ver refleja#o en base #e #atos es necesario acu#ir al mHto#o SaveCBan'esEF. ;n escenario como el #el se'un#o objeto que a're'amos, que tiene un Bijo EPaGs f Ciu#a#F se requiere eliminar to#os sus Bijos y lue'o si finalmente el Pa#re, #e lo contrario obten#remos una e7cepci>n. 0tra alternativa, es Babilitar la eliminaci>n en casca#a, se pue#e Bacer #irectamente sobe la relaci>n #e las tablas en la base #e #atos o evaluar lo que en esta li'a se propone. F Edit!ndo d!tos con Entity +r!)e(or9 1 Para e#itar un elemento, se si'ue un proce#imiento similar al que se'uimos para eliminarlo, lo recuperamos, mo#ificamos la propie#a# que #eseamos y SCN A"( "A(*0 al conte7to, 'uar#amos los cambios, asG1 static voi# <ainEstrin'VW ar'sF P usin' E 9&emo ntities conte7t Q ne% 9&emo ntities EFF P Pais pais Q Efrom p in conte7t.Pais %Bere p.Nombre QQ OColombiaO select pF.9irst0r&efaultEFM pais.Nombre Q OColombia #ita#aOM conte7t.SaveCBan'esEFM R R

Testin
Kttp:OO6*!nF !rci!Fc!r)on!.blo spot.co).!rO2P12OPQOintrod*ccionFlosFtestsF*nit!riosFtddFy.Kt)lTestin

45

.ntrod*cci4n ! los Tests 1nit!rios; T"" y 'oc9in

O l testin' pue#e probar la presencia #e errores pero no la ausencia #e ellos.O #s'er 8ybe &ij:stra l presente artGculo preten#e ser una 'ran intro#ucci>n a test unitarios y !&& y una breve intro#ucci>n a <oc:in'. *a presencia #e tests no 'aranti=a la ausencia #e errores a no ser que se cubran to#os los caminos posibles #el al'oritmo o #el proceso y #e aBG la importancia #e la cobertura #e c>#i'o, a mayor cobertura #e c>#i'o mayor se'uri#a# #e que no va a Baber nin'una casuGstica \#ram.tica], es #ecir, al'In caso no contempla#o que Ba'a que to#o o parte #e nuestro soft%are \se rompa]. Antes #e lle'ar a los tests unitarios y #e pasar al <oc:in' voy a Bacer un repaso #e al'unos conceptos 'enerales relaciona#os con pruebas #e soft%are. Test de 0!lid!ci4n O Tests de !cept!ci4n 8i:ipe#ia1 Proceso #e revisi>n #e 6ue el soft%are pro#uci#o cumple con las especificaciones #e cliente y cumple su cometi#o. Se $ali#a 6ue lo 6ue se Ba conse'ui#o es realmente lo 6ue el usuario realmente querGa . *a pre'unta a reali=arse es1 s esto lo que el cliente quiered ABora mismo lo que 'eneralmente se Bace en 'ran#es proyectos tener a un 'rupo #e testers proban#o casos #e uso, es #ecir, vien#o si se cumplen to#os los requisitos en ca#a paso #el caso #e uso, enten#ien#o por caso #e uso a una #escripci>n #etalla#a #e una o varias funcionali#a#es. Test de /*ncion!lid!d 8i:ipe#ia1 ;na prueba funcional es una prueba basa#a en la ejecuci>n, revisi>n y retroalimentaci>n #e las funcionali#a#es previamente #ise?a#as para el soft%are. *as pruebas funcionales se Bacen me#iante el #ise?o #e mo#elos #e prueba que buscan evaluar ca#a una #e las opciones con las que cuenta el paquete inform.tico. Test de inte r!ci4n 8i:ipe#ia1 Se refieren a la prueba o pruebas #e to#os los etementos in#ivi#uales que componen un proceso #e una sola ve=, asG pues, los m>#ulos in#ivi#uales son combina#os y proba#os en conjunto. Son las pruebas posteriores a las pruebas unitarias #e ca#a m>#ulo y prece#en a las pruebas #el sistema. Prueban varios componentes en conjunto. Hoy en #ia son las pruebas m.s Babituales y tambiHn pue#en implementarse como tests unitarios aunque no siempre son #eterministicos o repetibles, porque tienen #emasia#as variables en jue'o, y no siempre son Or.pi#osO, #e BecBo casi nunca lo son.

Test *nit!rio 8i:ipe#ia1 n pro'ramaci>n, una prueba unitaria es una forma #e probar el correcto funcionamiento #e un m>#ulo #e c>#i'o. sto sirve para ase'urar que ca#a uno #e los m>#ulos funciona correctamente por separa#o. *ue'o, con las pruebas #e inte'raci>n, se po#r. ase'urar el correcto funcionamiento #el sistema o subsistema en cuesti>n. *a i#ea es escribir casos #e prueba para ca#a funci>n no trivial o mHto#o en el mo#ulo #e forma que ca#a caso sea in#epen#iente #el resto. No enten#amos m>#ulos como clases enteras, incluso ni siquiera como mHto#os, #entro #e un mismo mHto#o, uno que conten'a varios bucles, se po#rGa #efinir to#o un conjunto #e pruebas cuyo objetivo sea verificar que #a#o unas precon#iciones o unos valores iniciales se cumplen unas postNcon#iciones, es #ecir, unas sali#as o unos esta#os finales. *o #etallarH un poco m.s a#elante cuan#o Bable #e la meto#olo'Ga AAA #e tests unitarios. Como ya se Ba #icBo Hstos son los tests m.s b.sicos y en ellos s>lo se prueba o una clase aisla#a o interacciones entre clases o bloques peque?os #e funcionali#a# y #eberGan cumplir siempre las si'uientes caracterGsticas1

4$

&eben ser repetibles y #eterminGsticos, es #ecir, ante unos inputs #ebo ser capa= #e #eterminar los outputs SC <P( , porque se los requisitos y no escribo c>#i'o a lo loco a ver que sale, y si ante #etermina#as situaciones sH que voy a tener #etermina#os resulta#os Hsto va a suce#er y se va a repetir siempre &eben Eo #eberianF se autom.ticos, $isual Stu#io yLo !eam 9oun#ation Server se encar'an #e ello en entornos <icrosoft y sH que otros entornos tambiHn incluyen frame%or:s para pasar baterGas #e tests unitarios. Test "ri0en "e0elop)ent F T"" Hay que enten#er bien para que est.n pensa#os los tests unitarios y no probar partes #el c>#i'o a lo loco y es aquG #on#e entra !&&. !&& si'nifica !est &riven &evelopment, es #ecir, #esarrollo 'uia#o por pruebas. s realmente sencillo e7plicarlo y to#os lo enten#er.n aunque no sean pro'rama#ores porque son tres pasos na#a m.s.

1i &efines una prueba en la que se pi#e cumplir cierto requisito. 2i scribes el c>#i'o que Bace que se cumpla ese requisito. 3i jecutas la prueba, si falla es porque el c>#i'o est. mal, si pasa pue#es atacar el si'uiente requisito. A 'ran#es ras'os es asG #e sencillo aunque el bucle en nuestro trabajo es un poco mas complejo aunque el si'uiente 'r.fico lo e7presa a la perfecci>n1 Como vemos, las pruebas unitarias fomentan que el #esarrolla#or mo#ifique el c>#i'o para mejorar su estructura lo que se Ba llama actualmente refactori=aci>n. Al Bacer !&& el #esarrolla#or se ci?e m.s a los requisitos y no a#elanta trabajo, cosa que suele #e'enerar en c>#i'o #eca#ente y =onas #e c>#i'o inutili=a#as. Al'o muy importante que poca 'ente menciona es que se pue#e #ocumentar el c>#i'o me#iante pruebas unitarias. Como Be #icBo, una prueba unitaria verifica que se cumple un requisito, al ele'ir bien la nomenclatura #e las pruebas unitarias po#remos saber a la perfecci>n como se comporta un servicio en nuestro sistema leyen#o tan s>lo lo tGtulos #e ca#a una #e las pruebas que cubren el c>#i'o #e #icBo servicio. <.s a#elante BarH una o varias #emostraciones #e !&& para que se vean los patrones AAA y la nomenclatura 8BenNCtSBoul# que nos ayu#ar.n a escribir tests m.s limpios y a #ocumentar me#iante tests respectivamente. c6uH aportan los tests unitarios y !&& a nuestros proyectos #e Soft%ared 6ui=. serGa m.s corto pre'untar quH cosas no aportan los tests unitarios y el !&& porque, #espues #e lo e7puesto Basta aquG vemos que los tests unitarios1 (e#ucen el nImero #e errores y bu's ya que Hstos, aplican#o !&&, se #etectan antes incluso #e crearlos. 9acili#a# para enten#er el c>#i'o, ya que eli'ien#o una buena nomenclatura los tests sirven #e #ocumentaci>n. 9acili#a# para mantener el c>#i'o ya que proveen #e una Omalla #e se'uri#a#O que nos prote'e ante cambios, pues, un error que sur'a al aplicar un cambio #eberGa ser #etecta#o Ey corre'i#oF antes #e subir ese cambio. Ayu#an a evitar re'resiones, es #ecir, rollbac:s por subi#as #e c>#i'o que rompen al'o. &an confian=a, 'racias a esa malla #e se'uri#a# 9acili#a# para #esarrollar si se aplica !&& pues nos ce?imos a los requisitos. Ayu#an a encontrar inconsistencias en los requisitos Ayu#an a especificar comportamientos Ayu#an a refactori=ar para mejorar la cali#a# #e nuestro c>#i'o EClean co#eUF

4%

A me#ioLlar'o pla=o aumentan EmucBoF la pro#uctivi#a#. Simplifican la inte'raci>n #e sistemas pues permiten lle'ar a la fase #e inte'raci>n con la se'uri#a# #e que ca#a m>#ulo in#epen#iente cumple con cierto 'ra#o #e cali#a# y est. funcionan#o como #eberGa, a#em.s re#ucen #r.sticamente los problemas y los tiempos #e#ica#os a la inte'raci>n porque nos permiten po#er probar o #epurar las relaciones #e un m>#ulo con el sistema sin necesi#a# #e #isponer #el sistema completo. `sto se lo'ra simulan#o o falsean#o comportamientos #e clases enteras con lo que se conoce como <oc:in'. J to#o esto repercute en lo que al cliente m.s le importa, el (0C, (eturn 0f Cnvestment en in'lHs o retorno #e la inversi>n en castellano, es #ecir, en si Ba inverti#o to#o Hste #inero en un soft%are que vale para al'o o no y, sobreto#o, el tiempo que va a tar#ar en amorti=ar Hsta inversi>n. !o#o Hsto est. muy bien, cver#a#d cA al'uien que no conociera na#a sobre tests unitarios y !&& no le Ban llama#o la atenci>nd Pero jojoU siempre Bay que consi#erar, como #ecGa al principio #e Hste artGculo, que los tests1 No 'aranti=an el H7ito #e un proyecto No ase'uran 144g #e cali#a# No son aplicables a to#o proyecto, ojal. lo fueran y vemos avances en ese senti#o ca#a #Ga. 0bli'an a pensar antes #e empe=ar a pro'ramarU Ecosa que se #eberGa Bacer siempre pero que la e7periencia me #ice que no es tan Babitual...F <itos sobre los tests unitarios1 O scribir pruebas unitarias es escribir el #oble #e c>#i'o.O *as pruebas siempre se #eben ir escribien#o a me#i#a que se #esarrolla el soft%are E!&&F. A me#i#a que #esarrollamos vamos proban#o nuestro c>#i'o lo que nos permite ase'urar que el m>#ulo que#a termina#o correctamente, libre #e errores. scribimos monos c>#i'o, os lo ase'uro.

O&esarrollar pruebas unitarias Bace que los tiempos #e #esarrollo Se incrementen, incrementan#o C asG los costes #el proyecto.O ntre #esarrollar sin tests y con tests, sinceramente, es m.s r.pi#o, a priori, #esarrollar sin probar na#a... *o Bemos BecBo Basta aBora, cnod Epo#ria estar #e acuer#o con esto en un #esarrollo #e an#ar por casa... F pero entre #esarrollar con pruebas unitarias y probar con mHto#os Omas rIsticosO, Hsta se'un#a manera es m.s lenta y mas cara. *a manera m.s r.pi#a #e #esarrollar soft%are es BaciHn#olo bien, si no #esarrollamos c>#i'o #e cali#a# y no reali=amos pruebas, los tiempos #e #esarrollo se po#r.n #isparar enormemente porque se incrementa el tiempo #e inte'raci>n, los tiempos #e #epuraci>n y el tiempo resolvien#o inci#encias, estabili=an#o el sistema, corri'ien#o #e bu's, etcHtera. A#em.s, mucBos pro#uctos tienen un mantenimiento evolutivo que implica el #esarrollo #e nuevas funcionali#a# y la correcci>n #e inci#encias. Sin un proceso a#ecua#o #e pruebas unitarias, los tiempos #e pruebas se #ispararan en fases posteriores, ya que ser. necesario probar y corre'ir tanto las nuevas funcionati#a#es como las funcionali#a#es ya e7istentes ante ca#a cambio. cCu.ntas veces al'uien Ba subi#o al'o y al cabo #e #os #Gas al'uien se #a cuenta #e que Bay un fallo en otra parte #el sistema por culpa #e aquella subi#ad

lnte r!ci4n Contin*! Al Bilo #e lo que estaba #icien#o, el control #e la cali#a# #e nuestras subi#as, Bay que Bablar #e la inte'raci>n continua. No se #eben confun#ir los tests #e inte'raci>n con el concepto #e inte'raci>n continua., ya Be Babla#o antes #e Hsto sin lle'ar a llamarlo inte'raci>n continua. Cnte'raci>n continua quiere #ecir que si un test que antes funcionaba falla tras una subi#a e7iste una re'resi>n entre el ultimo commit o subi#a testea#a y la actual. Cuantos menos commits se Ba'an entre el proceso #e pasar to#as las pruebas mejor pues ser. m.s f.cil ubicar

4'

y resolver cualquier error que nuestro #esarrollo Baya provoca#o. <i re'la es sencilla, antes #e subir Bay que bajar la Iltima versi>n #el c>#i'o por si al'In compa?ero Ba subi#o al'o, y se #eben pasar to#as las pruebas en local. Si to#os los tests pasan entonces po#emos subir con bastante tranquili#a#. Si trabajamos con !9S po#emos confi'urarlo para que en ca#a subi#a se pasen #e nuevo to#os los tests. 0tra re'la #iverti#a y que motiva al equipo a ase'urarse antes #e subir su c>#i'o es llevar un re'istro #e quien Ba roto la compilaci>n y Bacerlo #e una manera OcacBon#aO, por ejemplo, man#an#o a to#o el equipo una foto con la cara #e quien acaba #e romper la compilaci>n o #ejarle en su escritorio un set #e 'lobos #e Belio y una corona Basta que otro compa?ero Ola ca'ueO y rompa la compilaci>n. cNo suena #iverti#ad c6uien Ba #icBo que pro'ramar fuera aburri#od

n un servi#or #e inte'raci>n continua i#eal Ecomo !9SF #eberGamos po#er1 Pro'ramar la ejecuci>n #e tests Or.pi#osO Eante ca#a subi#a o ca#a Bora #urante la jorna#a laboral, eso #epen#er. #el proyectoF Pro'ramar tests OlentosO #iariamente, tests enfoca#os a la inte'raci>n o tests #e estrHs que sepamos que tar#an #emasia#o tiempo. 0btener fee#bac: #e ca#a commit o subi#a en cuesti>n #e minutos. T"": 'etodolo 7! AAA y no)encl!t*r! WKenF.tSKo*ld Hasta aBora Be Babla#o mucBo y Be pro'rama#o poco, vamos a ver con unos ejemplos pr.cticos #e quH va to#o Hsto. $oy a empe=ar con el ejemplo tGpico #e la calcula#ora. Supon'amos que nos Ban pe#i#o que Ba'amos una calcula#ora muy simple que sume #os nImeros enteros naturales positivos a prueba #e fallos. Como somos unos profesionales #el !&& vamos a crear primero la clase Calcula#ora!est y un primer mHto#o #e prueba que instancie una calcula#ora y que comprueba que el resulta#o #e sumar #os nImeros, por ejemplo 2 y 2 es el que tiene que ser, es #ecir, ). Erepetible y #eterministaF. *o primero que vemos es que Hste c>#i'o #e test falla porque ni siquiera e7iste la clase Calcula#ora asG que, como somos unos profesionales y practicamos los principios S0*C& ca#a ve= que pro'ramamos, vamos a empe=ar crean#o una interfa= CCalcula#ora ECSPF y una clase Calcula#ora que la implemente, ambas vacGas. `sto es a lo que en varias ocasiones Bemos llama#o refactori=ar, aBora Bemos BecBo una refactori=aci>n partien#o #es#e la na#a. Pero el c>#i'o #e pruebas si'ue fallan#o, nos falta el mHto#o Suma asG que lo vamos a crear en la interfa= y en la clase, vacGo con, por ejemplo un Oreturn N1MO Si ejecutamos la prueba evi#entemente va a fallar porque al sumar 2 @ 2 nos va a #evolver N1 y no va a cumplir la asertaci>n, es #ecir, la verificaci>n que Bemos impuesto a nuestro test. c6uH Bacemos aBorad Aueno, vamos a conse'uir que pase el test, cnod &evolvamos num1 @ num2. ABora si ejecutamos el test el test pasa.

Aien, Bemos avan=a#o pero nos que#an requisitos por cumplir, nos Ban pe#i#o que sean #os nImeros enteros positivos y a prueba #e fallos y nos Bemos que#a#o en O#os nImeros enterosO, nos que#a el positivos y el a prueba #e fallos, fallos que po#rGan venir #e un #esbor#amiento pero vamos por pasos, nuestro si'uiente requisito va a ser que sean positivos y vamos a se'uir los requisitos a rajatabla, es #ecir, si nos lle'a un nImero ne'ativo no nos vamos a inventar un mensaje ni un lo', no, vamos a lan=ar una e7cepci>n #e ar'umentos. mpecemos con el primer nImero1 Si ejecutamos el test falla porque en nuestra clase no estamos controlan#o eso.

4)

Habr. que refactori=arla para comprobar si el primer par.metro es menor que cero y lan=ar una Ar'ument0ut0f(an'e 7ception. l c>#i'o #e nuestra clase que#ar. asG1 Si aBora ejecutamos los tests pasan to#os, estamos en ver#e.

j"enialU Pues Ba'amos lo mismo con el si'uiente par.metro, con num2, primero el test y lue'o el c>#i'o que pasa el test1 J si ejecutamos los tres tests pasan to#os.

Como vemos Hste proceso iterativo e incremental #e testeo E!&&F es bueno pues, nos ce?imos a los requisitos sin inventarnos na#a, cosa a la que ten#emos to#os los #esarrolla#ores #e forma innata cuan#o los requisitos no son claros. $oy a obviar to#os los pasos pero voy a aabar los tests y la clase que se ci?e a los requisitos #el ejemplo. Primero los tests1

5*

c s mejorable Hste c>#i'od Pues se'uro que si pero no es el objetivo #e Hste artGculo apren#er CD sino Bacer una intro#ucci>n al !&& y a <oc:in'. 0bserva# que en to#os los tests Bemos BecBo m.s o menos lo mismo, Bemos crea#o y prepara#o el test, en este caso crean#o una calcula#ora y #an#o valor a las variables. &espuHs Bemos ejecuta#o lo que querGamos probar, en nuestro caso el mHto#o sumar, y #espuHs Bemos verifica#o que el resulta#o #e la prueba era el espera#o. n to#os los tests m.s o menos lo mismo, cciertod Pues jbienveni#o a la meto#olo'Ga AAAU

<eto#olo'fa AAA1 Arran'eNActNAssert s muy simple, lo acabamos #e ver1 Arran'e1 si'nifica preparar y #ar valores Act1 es actuar, ejecutar lo que se quiere probar Assert1 es ase'urarse #e que se Ba BecBo lo que se tiene que Bacer Hace unos a?os #escubrG, 'racias a "ary <clean Hall, Hsta manera #e escribir tests unitarios y en ver#a# me Ba facilita#o la vi#a, a mG y a los compa?eros que la Ban apren#i#o, interiori=a#o y aplica#o en sus #esarrollos. $oy a compartir en Hste artGculo su clase en aquel artGculo, BecBa mGa y renombra#a Bacia la meto#olo'Ga AAA1

`sta clase la ten'o en un proyecto que se llama Arran'eActionAssert, es un proyecto que incluyen #es#e Bace tiempo to#os mis proyectos #e tests. AAA y 8BenNCtSBoul# est.n intimamente relaciona#os, 8BenNCtSBoul# si'nifica, literalmente, Cuan#oN&eberGa. Cuan#o son las #os primeras #os aes, que en palabras #e "ary se pue#e tra#ucir como "iven !Bat y 8Ben, es #ecir, nuestras tres aes son "iven!BatN 8BenNCtSBoul#. s lo mismo y qui=. mas intuitivo, por ejemplo y al Bilo #el ejemplo anterior1 OCuan#o sumo #os nImeros enteros positivos #eberGa obtener la suma #e ambos.O Con la nomenclatura 8BenNCtSBoul# se pue#e cubrir to#a la l>'ica #e un al'oritmo complejo y #ocumenta por si sola porque, tan solo con ver los nombres #e los tests que cubren cierta funcionali#a#, se pue#e enten#er que Bace y ver to#a la l>'ica #e ne'ocio. $eamos como que#arGa el ejemplo #e la calcula#ora utili=an#o AAA como clase base #e nuestros tests y la nomenclatura 8BenN CtSBoul#... `sta serGa la primera apro7imaci>n en ;<* Eno Ba que#a#o e7actamente asG pero s>lo quiero que se vea la intenci>nF1

51

`ste serGa el c>#i'o #e pruebas1

Creo que ese c>#i'o es auto e7plicativo y las pruebas lo son aIn m.s, qui=. es #emasia#o lar'o y se po#rGa simplificar mucBo, por ejemplo, Bacien#o al'o muy comIn que es Bacer Arran'e y Act #entro #el mHto#o #e test en pruebas que esperan e7cepciones. 6ue no se pier#a na#ie, en la clase 8BenA##in'!%oNumbers po#rGa Baber meti#o, sueltos, ca#a uno #e los tests #e errores y Baberlos llama#o por ejemplo CtSBoul#(eturn<a7$alue"iven!Bat!BeSumCs 7actly<a7$alue y #entro #e ese mHto#o #e prueba po#rGa Baber BecBo1 Cobert*r! Antes #e entrar en temas #e <oc:in', parte importante #e Hste artGculo, y para relajarnos un poco quiero volver al principio1 O l testin' pue#e probar la presencia #e errores pero no la ausencia #e ellos.O Ja nos Ba que#a#o claro a to#os que la presencia #e tests no 'aranti=a la ausencia #e errores a no ser que se cubran to#os los caminos posibles #e nuestros al'oritmos, y #e aBG la importancia #e la cobertura #e c>#i'o. A mayor cobertura, mayor se'uri#a# #e que no va a Baber nin'una causistica O#ram.ticaO, al'In caso no contempla#o que Ba'a que to#o o parte #e nuestro soft%are Ose rompaO. E*o sH, me repito, pero es importanteF Se lle'a a la practica certe=a #e que no Bay errores cuan#o se Ban proba#o to#as los posibles caminos #e un al'oritmo. *a canti#a# #e caminos #epen#e #e la compleji#a# #e ca#a al'oritmo y #icBa compleji#a# se mi#e con lo que se conoce como compleji#a# ciclom.tica. Co)ple6id!d ciclo)Itic! 8i:ipe#ia1 *a compleji#a# ciclom.tica Een in'lHs, cyclomatic comple7ityF es una mHtrica #el soft%are que proporciona una me#ici>n cuantitativa #e la compleji#a# l>'ica #e un pro'rama. s una #e las mHtricas #e soft%are #e mayor aceptaci>n, ya que Ba si#o concebi#a para ser in#epen#iente #el len'uaje. Se utili=a, entre otras cosas para planificaci>n #e pruebas1 el an.lisis matem.tico Ba #emostra#o que la compleji#a# ciclom.tica in#ica el nImero e7acto #e casos #e prueba necesarios para probar ca#a punto #e #ecisi>n en un pro'rama.

52

Sien#o1 CC Q compleji#a# ciclomatica A Q NImero #e aristas #el 'rafo. ;na arista conecta #os vHrtices si una sentencia pue#e ser ejecuta#a inme#iatamente #espuHs #e la primera. N Q NImero #e no#os #el 'rafo correspon#ientes a sentencias #el pro'rama. P Q NImero #e componentes cone7os correspon#ientes a las #iferentes subrutinas, funciones o mHto#os. ntonces1 CC Q A N N @ P No voy a entrar en ejemplos #e c.lculo #e la compleji#a# ciclom.tica pero si al'uien quiere saber m.s aquG #ejo Hste enlace. ABora pasemos, por fin, a <oc:in'... JA*: es 'oc9in D s ;na tHcnica para testar soft%are en la que se simulan partes #el sistema con las que el objeto a testar tiene al'una #epen#encia. ;n moc: es un objeto O#ummyO, son Ofa:esO #e partes #el sistema a las que se pue#e #efinir su comportamiento O0n tBe flyO. cC>mo es posible Hstod 9.cil, un moc: usa la interfa= #e un objeto real y la implementa y si Bemos se'ui#o mGnimamente los principios S0*C& po#emos sustituir una instancia #e nuestro objeto falsea#o, nuestro moc:, por el objeto que en reali#a# se esperaba. (epito, el objeto que queremos probar utili=a un objeto Omoc:eableO, y lo es porque implementa cierta interfa= que #efine su comportamiento. Al objeto testeable no le importa en reali#a# cual #e los #os objetos usa, no sabe si es una implementaci>n real o es un fa:e. n el fon#o no #eja #e ser polimorfismo aplica#o me#iante inyecci>n o inversi>n #e #epen#encias. &C obli'a a separar componentes Para testar Bace falta aislar m>#ulos Aislar m>#ulos implica quitar #epen#encias <oc:in' permite simular otros m>#ulos

r'o 1 'oc9in &oc9sRR `ste artGculo querGa ser una intro#ucci>n a !&& y <oc:in' y no un artGculo sobre <oc:in', por eso, #espuHs #e varios #Gas preparan#olo acabo #e #eci#ir #ejar para un si'uiente artGculo el <oc:in' propiamente #icBo, en castellano, claro, pero voy a recomen#ar al'una lectura que estoy se'uro que pue#e servir #e 'uGa para quien Baya leG#o Basta aquG y no pue#a esperar al si'uiente aertGculo. Ho% to use <oq moc:in' library Aasic moc:in' %itB <oq Ae''inin' %itB <oq Como comentario final quiero insistir en que merece la pena tener siempre presentes los principios S0*C& y "(ASP o principios para la asi'naci>n #e responsabili#a#es, los patrones #e #ise?o y en concreto la inyecci>n #e #epen#encias E&CF y el principio en el que se basa, la inversi>n #el control EloCF. !ener estos conceptos claros nos facilitar. el testin' me#iante <oc:in' y en 'eneral, #icBos principios nos aportar.n profesionali#a# #esarrollan#o soft%are. AIn ten'o pen#iente una serie #e artGculos sobre "(ASP y otra serie #e artGculos sobre patrones #e #ise?o entre los que est. &C, to#os ellos con ejemplos #e c>#i'o y #ia'ramas ;<* reali=a#os por mG. n concreto para el #e patrones #e #ise?o querGa Bacerlo, y ya lo Be empe=a#o, utili=an#o !&& y moc:in'. !iempo al tiempo.

53

54

Vous aimerez peut-être aussi