Fejlett Programozási Technikák 2.

Slides:



Advertisements
Hasonló előadás
© Kozsik Tamás Különböző nyelvekhez igazítás Internationalization - i18n.
Advertisements

4. alkalom – Hálózat Kezelés
Osztály leszármaztatás

Kamarai prezentáció sablon
Erőállóképesség mérése Találjanak teszteket az irodalomban
Mellár János 5. óra Március 12. v
Adatbányászati technikák (VISZM185)
Öröklődés 2..
RMI = Remote Method Invocation
© Kozsik Tamás Tömbök, kollekciók és egyéb alaposztályok.
© Kozsik Tamás Beágyazott osztályok A blokkstrukturáltság támogatása –Eddig: egymásba ágyazható blokk utasítások Osztálydefiníciók is egymásba.
Tanszéki konzulens: Horváth Ákos Készítette: Kóródi Norbert.
Bevezetés a Java programozásba
Fájlkezelés, IO Kivételkezelés Belső osztályok
1 Fejlett Programozási Technikák 2. 15/9. Fejlett Programozási Technológiák 2. 2 Az előző mai előadás tartalma: Számítógépes biztonság Jáva és a biztonság.
Abstract osztályok és interface-ek Beolvasás és kiíratás 7. gyakorlat.
Elektronikai Áramkörök Tervezése és Megvalósítása
Fejlett Programozási Technológiák II. Világos Zsolt 7. gyakorlat.
9. Háttér logika Dr. Bilicki Vilmos Szegedi Tudományegyetem
Tömbök ismétlés Osztályok Java-ban Garbage collection
Ember László XUBUNTU Linux (ami majdnem UBUNTU) Ötödik nekifutás 192 MB RAM és 3 GB HDD erőforrásokkal.
Az objektum-orientált tervezési alapelvek kritikai vizsgálata
A Java programozási nyelvSoós Sándor 1/17 Java programozási nyelv 4. rész – Osztályok II. Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai.
Java programozási nyelv 3. rész – Osztályok I.
Osztott alkalmazások kezelése. VIR elosztott architektúra indítékai: - meglévő komponensek integrációja - WEB / Internet elterjedése (nemzetköziség) -
WEB Technológiák Dr. Pance Miklós – Kolcza Gábor Miskolci Egyetem.
WSDL alapismeretek A WSDL (Web Services Description Language – Web szolgáltatások leíró nyelv) egy XML-alapú nyelv a Web szolgáltatások leírására és azok.
C# tagfüggvények.
JSP és JavaBean JavaServer Pages és Java Beans Fabók Zsolt Általános Informatikai Tanszék Miskolci Egyetem.
C# tagfüggvények.
Krizsán Zoltán iit 1.2.  Nem kell vizuális felületnek lennie.  Delegátumok segítségével valósíthatja meg a.NET. Krizsán Zoltán iit Delegátumok C#-ban2.
SPRING FRAMEWORK bemutatása
Szmetankó Gábor Greencode Kft.
6. előadás Parametrikus polimorfizmus. Generikus programozás. Az Ada sablonok.
Szerkezeti elemek teherbírásvizsgálata összetett terhelés esetén:
Kivételkezelés.
WEB MES (webes gyártásirányító rendszer)
DRAGON BALL GT dbzgtlink féle változat! Illesztett, ráégetett, sárga felirattal! Japan és Angol Navigáláshoz használd a bal oldali léptető elemeket ! Verzio.
PHP I. Alapok. Mi a PHP? PHP Hypertext Preprocessor Szkriptnyelv –Egyszerű, gyors fejlesztés –Nincs fordítás (csak értelmező) Alkalmazási lehetőségek:
P ROGRAMOZÁS C# - BAN Kivételkezelés. P ÉLDA I. Nullával való osztás miatt kapjuk a hibaüzenetet.
Perzisztencia-megoldások Java Technológiával Molnár István, Simon Géza.
Programrendszerek Fejlesztése
Java – adatbázisok elérése
szakmérnök hallgatók számára
Java 2 Enterprise Edition
Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
1 Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Hernyák Zoltán Programozási Nyelvek II.
Javascript Microsoft által készített kiegészítése Statikus típusosság Nagy projektek Windows 8 fejlesztésénél WinRT egy részét ebben írták Nyílt forráskódú,
A klinikai transzfúziós tevékenység Ápolás szakmai ellenőrzése
QualcoDuna interkalibráció Talaj- és levegövizsgálati körmérések évi értékelése (2007.) Dr. Biliczkiné Gaál Piroska VITUKI Kht. Minőségbiztosítási és Ellenőrzési.
Java programozási nyelv Metódusok
Java programozási nyelv Adatbekérés konzolról
Java web programozás 11..
Enterpise JavaBeans Simon Balázs
Webprogramozó tanfolyam
> aspnet_regiis -i 8 9 TIPP: Az „Alap” telepítés gyors, nem kérdez, de később korlátozhat.
A KÖVETKEZŐKBEN SZÁMOZOTT KÉRDÉSEKET VAGY KÉPEKET LÁT SZÁMOZOTT KÉPLETEKKEL. ÍRJA A SZÁMOZOTT KÉRDÉSRE ADOTT VÁLASZT, VAGY A SZÁMOZOTT KÉPLET NEVÉT A VÁLASZÍV.
Webes MES keretrendszer fejlesztése Kiss Miklós Dániel G-5S8 Tervezésvezető: Dr. Hornyák Olivér.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás I. 7. gyakorlat.
1Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Programozás I. 6. gyakorlat.
TÁMOP /1-2F JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam Osztályok, objektumok definiálása és alkalmazása. Saját.
Programozás III JPA.
EJB üzenet vezérelt bean (MDB)
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
JBoss Wildfly Kalla Mór
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
Előadás másolata:

Fejlett Programozási Technikák 2. 15/12

Az előző előadás tartalma: J2EE JNDI RMI Corba

Forrás Ed Roman: Mastering Enterprise Java Beans http://www.theserverside.com/ http://www.theserverside.com/books/wiley/masteringEJB/downloads/MasteringEJB1.zip (2.0 előtti verzióról szól !!)

A mai előadás tartalma: Java Enterprise Edition EJB specifikáció (2.0) EJB komponensek Remote, Home, Local, Local Home interfész Session Bean Stateless Statefull Entity Bean BMP CMP Message Driven Bean Durable Non Durable

Példa Kliens Kliens Kliens Kliens Szerver Szerver Szerver Szerver Címtár Adatbázis Adatbázis

Megoldandó problémák Távoli eljárás hívás Terhelés elosztás Transzparens hiba tűrés Együttműködés háttér rendszerekkel Tranzakció kezelés Klaszterezés Dinamikus telepítés Tiszta leállítás Naplózás auditálás Rendszer menedzsment Szálkezelés MOM Objektum életciklus Erőforrás gyűjtemény Biztonság Gyorstár …

Megoldás Minden cég megírja a saját szoftverét Komplex problémák Egyedi tudás Drága Előre megírt komponenseket használ (MiddleWare) Tesztelt, kevesebb hibával rendelkező Olcsóbb (TCO) A saját problémájával foglalkozhat

Komponens architektúrák Explicit MiddleWare Komplex API gyűjtemény melyet nekünk kell hívogatnunk Implicit MiddleWare Csak az üzleti logikával kell foglalkoznunk Konfiguráció fájl -> Kérés elfogó (Request Interceptor) Megoldások: CORBA Component Model .NET J2EE - EJB

Enterprise Java Beans EJB: Érvek EJB mellett Szerver oldali komponens Java interfészek halmaza Specifikáció mely leírja a komponensek és az alkalmazásszerverek együttműködését Érvek EJB mellett Sokan támogatják Nyílt szabvány, elvileg gyártó független Gyors alkalmazás fejlesztés Platform független

EJB rendszer Bean fejlesztő Alkalmazás szintetizáló EJB telepítő Telepíthető adott funkciót ellátó komponenesket gyárt Alkalmazás szintetizáló Ő látja át az adott problémát és tervezi meg hozzá az alkalkalmazást EJB telepítő Biztonsági, integrációs kérdések (LDAP, tűzfal, …) Rendszer Adminisztrátor Rendszer menedzsment, monitorozás, … Alkalmazás szerver gyártó Fejlesztő eszköz gyártók

EJB típusok (2.1) Viszony Bab (Session Bean) Entitás Bab (Entity Bean) Az üzleti folyamat modellezésére szolgál Munkafolyamat, árazás, hitel kártya engedélyező, … Entitás Bab (Entity Bean) Az üzleti adatot modellezik Termék, egyed, rendelés, … Üzenet vezérelt Bab (Message Driven Bean) Hasonló mint a viszony bab, csak üzenetekkel lehet kommunikálni vele

Mitől EJB az EJB? javax.ejb.EnterpriseBean interfész Üres interfész, csak a neve a fontos A java.io.Serializable interfészt bővíti Az alábbi interfészek származnak belőle: javax.ejb.EntityBean javax.ejb.SessionBean javax.ejb.MessageDrivenBean

Az EJB objektum Nem kapcsolódunk közvetlenül az EJB-hez Az EJB tároló elfogja a hívást és delegálja a Bab példánynak (Instance Pooling) EJB objektum ragasztóként funkcionál, Ragasztó Eszköztár A tárló generálja (tárolónként más-más lehet) Implicit MiddleWare Kivételek (transzparent fail-over): Alkalmazás szintű Rendszer szintű

Remote Interface Ezzel tudatjuk az EJB objektummal, hogy mely metódusokat szeretnénk távolról elérni (RMI-IIOP, RemoteExeption) Őse: javax.ejb.EJBObject extends java.rmi.Remote EJBHome getEJBHome() Handle getHandle() java.lang.Object getPrimaryKey() boolean isIdentical(EJBObject obj) void remove()

Home Objektum A kliens tőle kéri az EJB példányt (Helyszín Transzparens) Feladata: EJB objektumok létrehozása Meglévő EJB objektumok megtalálása EJB objektumok eltávolítása Tároló specifikus Automatikusan generált

Home Interfész Tudja hogyan kell az EJB objektumot inicializálni javax.ejb.EJBHome getEJBMetaData getHomeHandle remove

Local Interfész A Home interfész használata lassú Helyette: Kliens a helyi csonkhoz fordul A helyi csonk átalakítja a paramétereket hálózaton hasznáhatóvá A váz Visszaalakítja őket A váz meghívja az EJB objektumot Az EJB végrehajtja a szükséges MiddleWare műveleteke Az EJB objektum meghívja Bab példányt és így vissza Helyette: A kliens meghívja a lokális objektumot A lokális objektum elvégzi a megfelelő MiddleWare műveleteket A Lokális objektum meghívja a Bab példányt javax.ejb.EJBLocalObject EJBLocalHome getEJBLocalHome() java.lang.Object getPrimaryKey() boolean isIdentical(EJBLocalObject obj) void remove() Problémák: Nincs távoli objektum hozzáférés (csak azonos processzen belül) A paraméterek referencia szerint adódnak át (később problémás lehet átalakítani)

Telepítés leírók Forrás kódok nélkül is hangolható a rendszer XML fájlok Ezekben specifikálhatjuk azokat a szolgáltatásokat melyekre szükségünk van a Tároló részéről Bab menedzsment Tranzakció Biztonság …

Ejb-jar fájlok Ezekben a fájlokban fogjuk össze komponensünket Elemei: EJB class fájlok Home interfész Local interfész Remote interfész Local Home interfész Telepítés leíró Gyártó specifikus konfig. fájlok

Egy minta viszony EJB Session Bean Remote Interface Home Interface Local Interface LocalHome Interface

Viszony Bab import javax.ejb.SessionContext; public class HelloBean implements javax.ejb.SessionBean { public void ejbCreate() { System.out.println("ejbCreate()"); } public void ejbRemove() { System.out.println("ejbRemove()"); } public void ejbActivate() { System.out.println("ejbActivate()"); } public void ejbPassivate() { System.out.println("ejbPassivate()"); } public void setSessionContext(SessionContext ctx) { System.out.println("setSessionContext()"); } public String hello() { System.out.println("hello()"); return "Hello, World!"; } }

Távoli Interfész, Lokális Interfész public interface Hello extends javax.ejb.EJBObject { public String hello() throws java.rmi.RemoteException; } public interface HelloLocal extends javax.ejb.EJBLocalObject public String hello();

Home, LocalHome interfész public interface HelloHome extends javax.ejb.EJBHome { Hello create() throws java.rmi.RemoteException, javax.ejb.CreateException; } public interface HelloLocalHome extends javax.ejb.EJBLocalHome HelloLocal create() throws javax.ejb.CreateException;

Telepítés leíró !DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"> <ejb-jar> <enterprise-beans> <session> <ejb-name>Hello</ejb-name> <home>HelloHome</home> <remote>Hello</remote> <local-home>HelloLocalHome</local-home> <local>HelloLocal</local> <ejb-class>HelloBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> </ejb-jar>

Kliens public class HelloClient { public static void main(String[] args) throws Exception { Properties props = System.getProperties(); Context ctx = new InitialContext(props); Object obj = ctx.lookup("HelloHome"); HelloHome home = (HelloHome) javax.rmi.PortableRemoteObject.narrow(obj, HelloHome.class); Hello hello = home.create(); System.out.println(hello.hello()); hello.remove(); }

Teljes működés

Viszony bab (Session Bean) Üzleti folyamatot valósít meg Nem mentődnek el a tartós tároló helyre: Rövid életűek (a kliens kód hívása alatt élnek) Általában nem élik túl a szerver leállásokat Két típusa van: Állapot mentes (Stateless) Egy metódus hívásig él Nem őrzi meg állapotát Minden egyede egyenlő, újrahasznosítható, készletezhető Állapottal rendelkező (Statefull) Több egymást követő kérést tranzakciót képes kiszolgálni Megőrzi az állapotát (a viszony idejére) Készletezés: passivation, activation (erőforrások menedzselése)

Egyed bab (Entity bean) Egy állandó adat memóriabeli Java reprezentációja Tudja, hogyan kell elmentenie és kiolvasnia magát A memóriabeli példányát módosítva módosul a tartós adat is (ejbLoad(), ejbStore() a szinkronizáció a tároló feladata) Lehetséges megoldások: Serialization Objet-Relational Mapping Objektum adatbázisok Csak egy szál férhet hozzá egy időben -> több EJB ugyanaz az adat -> tranzakciók Gyűjteményezhető (Pooling) ejbActivate(), ejbPassivate() ejbStore(), ejbLoad() Adatbázis kód: Bean Managed Persistence Entity Bean – BMP Container Managed Persistence Entity Bean - CMP

Egyed bab Létrehozása, törlése (adatbázissal együtt!): ejbCreate() ejbRemove() Elsődleges kulcsot megvalósító osztály Az egyed babok kereshetőek Finder metódusok (home interfész) Az adatbázis módosításával módosul az egyed bab is (új is létrejön)!

Egyed bab környezet Javax.ejb.EntityContext extends EJBContext getEJBLocalObject(), getEJBObject() – (this) getPrimaryKey() – connection pooling ejbLoad ejbRemove

BMP Nekünk kell kézzel kódolnunk az adatbázis hozzárendelést javax.ejb.EntityBean setEntityContext ejbFind<..>– csak itt kell implementálni pl.: select id from x where w > 0, PrimaryKey ejbFindTheBiggest, … kötelező ejbFindByPrimaryKey ezeket meg kell adni a Local, vagy home interfészben EJBObject find<…> ejbHome<..> – globális műveletek (sorok megszámolása) ejbCreate – INSERT INTO … ejbActivate – socket, …. Nyitás ejbLoad – getPrimaryKey, Select … ejbStore – UPDATE ejbPassivate – socket,… zárás ejbRemove – getPrimaryKey, delete

Példa Remote interface Home interface PK Bean Deployment Descriptor

Távoli interfész public interface Account extends EJBObject { public void deposit(double amt) throws AccountException, RemoteException; public void withdraw(double amt) throws AccountException, RemoteException; public double getBalance() throws RemoteException; public String getOwnerName() throws RemoteException; public void setOwnerName(String name) throws RemoteException; public String getAccountID() throws RemoteException; public void setAccountID(String id) throws RemoteException; }

Helyi interfész public interface AccountHome extends EJBHome { Account create(String accountID, String ownerName) throws CreateException, RemoteException; public Account findByPrimaryKey(AccountPK key) throws FinderException, RemoteException; public Collection findByOwnerName(String name) throws FinderException, RemoteException; public double getTotalBankValue() throws AccountException, RemoteException; }

Elsődleges Kulcs public class AccountPK implements java.io.Serializable { public String accountID; public AccountPK(String id) { this.accountID = id; } public AccountPK() { public String toString() { return accountID; public int hashCode() { return accountID.hashCode(); public boolean equals(Object account) { return ((AccountPK)account).accountID.equals(accountID);

Bean public class AccountBean implements EntityBean { protected EntityContext ctx; private String accountID; // PK private String ownerName; private double balance; public double getBalance() { System.out.println("getBalance() called."); return balance; } public void setOwnerName(String name) { System.out.println("setOwnerName() called."); ownerName = name; …

Bean: ejbFind… public Collection ejbFindByOwnerName(String name) throws FinderException { PreparedStatement pstmt = null; Connection conn = null; Vector v = new Vector(); try { System.out.println("ejbFindByOwnerName(" + name + ") called"); conn = getConnection(); pstmt = conn.prepareStatement("select id from accounts where ownerName = ?"); pstmt.setString(1, name); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { String id = rs.getString("id"); v.addElement(new AccountPK(id));} return v; } catch (Exception e) { throw new FinderException(e.toString());} finally { try { if (pstmt != null) pstmt.close(); } catch (Exception e) {} try { if (conn != null) conn.close(); }catch (Exception e) {}

Bean: Remove public void ejbRemove() throws RemoveException { AccountPK pk = (AccountPK) ctx.getPrimaryKey(); String id = pk.accountID; PreparedStatement pstmt = null; Connection conn = null; try { conn = getConnection(); pstmt = conn.prepareStatement("delete from accounts where id = ?"); pstmt.setString(1, id); if (pstmt.executeUpdate() == 0) { throw new RemoveException("Account " + pk + " failed to be removed from the database"); } catch (Exception ex) {throw new EJBException(ex.toString());} finally { try { if (pstmt != null) pstmt.close(); } catch (Exception e) {} try { if (conn != null) conn.close(); }catch (Exception e) {}

Telepítés leíró/1 <ejb-jar> <enterprise-beans> <entity> <ejb-name>Account</ejb-name> <home>examples.AccountHome</home> <remote>examples.Account</remote> <local-home>examples.AccountLocalHome</local-home> <local>examples.AccountLocal</local> <ejb-class>examples.AccountBean</ejb-class> <persistence-type>Bean</persistence-type> <prim-key-class>examples.AccountPK</prim-key-class> <reentrant>False</reentrant> <resource-ref> <res-ref-name>jdbc/ejbPool</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> </entity> </enterprise-beans>

Telepítés leíró /2 <assembly-descriptor> <container-transaction> <method> <ejb-name>Account</ejb-name> <method-intf>Local</method-intf> <method-name>*</method-name> </method> <method-intf>Remote</method-intf> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar>

CMP A bab fejlesztő nem tudja milyen adtabázist fognak használni A forráskódot nem szeretné kiadni Szeparált adatbázis kezelés/ üzleti logika A tároló fogja legenerálni a szükséges kódot a mi osztályunkból származtatva A mezők az alosztályban vannak definiálva (ez tároló függő) A get/set metódusok az alosztályban vannak definiálva Az ősosztályt mint absztrakt osztályt kell definiálni! A megfelelő absztrakt get/set metódusokkal A telepítés leíróból veszi a szükséges információkat (Abstract Persistence Schema) Saját lekérdező nyelv EJB-QL (SELECT OBJECT(a) FROM Accoun As a)

CMP metódusok ejbSelect<..> – ezzel is kitehetjük az SQL-t a leíróba (ejbSelectAllAccountBalances) Csak a babon belül hívható Absztrakt metódus ejbHome<..> ezen belül használjuk az ejbSelect-et

Példa Bab Telepítő

Bab public abstract class ProductBean implements EntityBean { protected EntityContext ctx; public ProductBean() { } public abstract String getName(); public abstract void setName(String name); public abstract String getDescription(); public String ejbCreate(String productID, String name, String description, double basePrice) { System.out.println("ejbCreate() called"); setProductID(productID); setName(name); setDescription(description); setBasePrice(basePrice); return productID; }

Telepítés leíró <ejb-name>Product</ejb-name> <home>examples.ProductHome</home> <remote>examples.Product</remote> <ejb-class>examples.ProductBean</ejb-class> <persistence-type>Container</persistence-type> <prim-key-class>java.lang.String</prim-key-class> <reentrant>False</reentrant> <cmp-version>2.x</cmp-version> <abstract-schema-name>ProductBean</abstract-schema-name> <cmp-field> <field-name>name</field-name> </cmp-field> <primkey-field>productID</primkey-field> <query> <query-method> <method-name>findByName</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </query-method> <ejb-ql> <![CDATA[Select OBJECT(a) FROM ProductBEan AS a WHERE name = ?1]]> </ejb-ql> </query> </entity>

BMP, CMP életciklus

Üzenet vezérelt bab (Message driven bean) Az előző komponensek RMI-IIOP-ot használtak kommunikációra Hátrányai: A kliensnek várnia kell a válaszra (nem engedélyezetett a szál kezelés !!) Nem megbízható Egyszerre csak egy egyeddel kommunikál Message Oriented MiddleWare MSMQ, IBM MQSeries, … cég függő JMS szabványos igyekszik lenni (API/SPI)

JMS API Messaging Domains: Publish/subscribe Point-to-Point

Üzenet vezérelt bab Teljesen el van különítve a többi komponenstől Nincs home, remote, local, localhome interfész Egy üzleti metódusuk van onMessage() menet közben deríti ki mit is kapott (instanceof) Nincs visszatérési értékük Nem tudnak kivételt küldeni a küldőnek Állapotmentesek Tartós vagy nem tartós listatagok Tartós – minden üzenetet megkap akkor is ha nem aktív Nem tartós csak azokat kapja meg amikor aktív volt javax.jms.MessageListener onMessage() javax.ejb.MessageDrivenBean ejbRemove setMessageDrivenContext

Példa: Bean public class LogBean implements MessageDrivenBean, MessageListener { protected MessageDrivenContext ctx; public void setMessageDrivenContext(MessageDrivenContext ctx) { this.ctx = ctx; } public void ejbCreate() { System.err.println("ejbCreate()"); } public void onMessage(Message msg) { TextMessage tm = (TextMessage) msg; try { String text = tm.getText(); System.err.println("Received new message : " + text); } catch(JMSException e) { e.printStackTrace(); } public void ejbRemove() { System.err.println("ejbRemove()");

Telepítés leíró <ejb-jar> <enterprise-beans> <message-driven> <ejb-name>Log</ejb-name> <ejb-class>examples.LogBean</ejb-class> <transaction-type>Container</transaction-type> <message-driven-destination> <destination-type>javax.jms.Topic</destination-type> </message-driven-destination> </message-driven> </enterprise-beans> </ejb-jar>

Összefoglaló Remote, Home, Local, Local Home interfész Session Bean Stateless Statefull Entity Bean BMP CMP Message Driven Bean Durable Non Durable

A következő előadás tartalma .NET architektúra IL C#