.NET (uitspraak: dotNET) is een applicatieframework ten behoeve van de naadloze samenwerking van applicaties en bibliotheken geschreven in verschillende programmeertalen. Het is ontwikkeld door Microsoft. .NET is volledig beschreven in publieke ECMA-standaarden, en is daarmee niet uitsluitend voor Microsoft-toepassingen. De Common Language Infrastructure, de officiële naam voor .NET is beschreven in ECMA-standaard 335, de nieuw ontwikkelde taal C# in ECMA-standaard 334.
De .NET-technologie is duidelijk geïnspireerd door Java. Nadat Microsoft de Java Virtual Machine uitbreidde voor een betere uitwisselbaarheid met het Windows-platform hetgeen in strijd was met de licentievoorwaarden van Sun Microsystems, de eigenaar van Java, die deze uitbreidingen uiteindelijk middels de rechter moest sanctioneren, besloot Microsoft Corporation samen met Hewlett-Packard en Intel Corporation een gezamenlijke standaard te ontwikkelen, wat resulteerde als basis voor .NET-framework. Dit verenigt de voordelen van de Java-principes met een grote uitwisselbaarheid met de al bestaande Windows-programmeeromgevingen, wat het tot een zeer interessant ontwikkelplatform maakt voor veel van de software die, voor .NET bestond, in Visual Basic of C++ werd ontwikkeld.
Net als bij Java worden programma's bij .NET niet gecompileerd tot machinecode maar tot een tussentaal (common intermediate language of CIL). Deze wordt dan vervolgens uitgevoerd door een runtime engine (VES). Vergelijk dit met de Java Virtual Machine. Deze opzet levert een abstractie op van de onderliggende machine (inclusief besturingssysteem en diensten, alsmede datatypes) en maakt dat veel verschillende programmeertalen ontworpen kunnen worden voor eenzelfde, gegarandeerde basis aan faciliteiten.
De Microsoft-implementaties worden alleen ontwikkeld voor Windows, maar er zijn ook opensourceimplementaties van .NET beschikbaar. De belangrijkste daarvan is Mono, dat is opgezet met als specifiek doel om het programmeren in .NET voor Linux te ondersteunen, en daar ook aardig in slaagt. De ontwikkeling loopt echter hier en daar achter op de voortdurende uitbreidingen in Microsoft-implementaties.
Eind 2014 maakte Microsoft bekend de broncode van het .NET Framework gedeeltelijk beschikbaar te stellen als opensourcesoftware.[2] Het gaat hierbij voornamelijk om de runtime en de verwante kerntechnologieën, zoals ASP.NET, de "Roslyn" .NET-compiler, het .NET Micro Framework, .NET Rx en de programmeertalen Visual Basic en C#.[2] Windows Forms blijft bijvoorbeeld closed source.[2]
Microsoft zal zich ook meer richten op platformonafhankelijkheid door de ondersteuning voor het .NET Framework uit te breiden naar Linux en Mac OS X.[3]
Het .NET-framework wordt meegeleverd vanaf Windows XP en Windows 2003 Server, maar is ook beschikbaar voor oudere versies van Windows. Ook zijn er diverse implementaties van de ECMA-standaarden te downloaden, sommige inclusief broncode.
Het doel van de Common Language Infrastructure, of CLI, is het verstrekken van een taal-neutraal platform voor applicatie - ontwikkeling en de uitvoering, inclusief functies voor exception handling, garbage collection, veiligheid en interoperabiliteit. Door de implementatie van de belangrijkste aspecten van het .NET Framework binnen de werkingssfeer van de CLR, zal deze functionaliteit niet worden gebonden aan een enkele taal, maar zal beschikbaar zijn over de vele talen ondersteund door het kader. Microsofts implementatie van de CLI is de Common Language Runtime, ook wel CLR genoemd.
Assembly's
De CIL-code zit in de .NET-assembly's. Zoals beschreven in de specificatie, zijn assembly's opgeslagen in het Portable Executable (PE) formaat, gemeenschappelijk op het Windows-platform voor alle DLL- en EXE-bestanden. De assembly bestaat uit een of meer bestanden, waarvan er een het manifest moet bevatten, dat de metadata voor de assembly heeft. De volledige naam van een assembly (niet te verwarren met de bestandsnaam op de harde schijf) bevat de eenvoudige naam, versie, cultuur en publiekesleuteltoken. De publiekesleuteltoken is een unieke hash, gegenereerd wanneer de assembly is samengesteld, dus twee assembly's met dezelfde publieke sleutel zijn gegarandeerd identiek in het oogpunt van het framework. Een privésleutel kan ook worden gespecificeerd alleen bekend bij de maker van de assembly en kan worden gebruikt voor een sterke naamgeving en om te garanderen dat de assembly is van dezelfde auteur als er een nieuwe versie van de assembly is samengesteld (verplicht om een assembly te kunnen toevoegen aan de Global Assembly Cache).
Security
.NET heeft zijn eigen veiligheidsmechanisme met twee algemene kenmerken: Code Access Security (CAS), en validatie/verificatie. Code Access Security is gebaseerd op bewijsmateriaal dat is geassocieerd met een specifieke assembly. De bron van de assembly is een typisch punt van bewijs (of het is geïnstalleerd op de lokale computer of is gedownload van het intranet of internet). Code Access Security gebruikt het bewijs om bepaalde machtigingen te verlenen aan de code. Andere code kan eisen dat aanroepende code een specifieke toestemming krijgt. De vraag zorgt ervoor dat de CLR een call stack walk uit zal voeren: elke assembly van elke methode in de call stack is gecontroleerd op de vereiste toestemming, als de assembly geen toestemming heeft dan wordt er een beveiliginguitzondering uitgevoerd.
Wanneer een assembly wordt geladen voert de CLR diverse tests uit. Twee van die tests zijn validatie en verificatie. Tijdens de validatie controleert de CLR dat de assembly geldige metadata en CIL-code bevat, en of de interne tabellen correct zijn. Verificatie is niet zo nauwkeurig. Het verificatiemechanisme controleert of de code iets doet dat 'onveilig' is. Het gebruikte algoritme is vrij conservatief, vandaar dat soms code die "veilig" is niet erdoor komt. Onveilige code wordt alleen uitgevoerd als de assembly het 'verificatie overslaan'-privilege heeft, dat in het algemeen betrekking heeft op code die is geïnstalleerd op de lokale machine.
.NET Framework maakt gebruik van AppDomains als een mechanisme voor het isoleren van code die wordt gedraaid in een proces. AppDomains kunnen geïnitialiseerd worden en vervolgens kan er programmeercode in en uit gestuurd worden. Deze AppDomains kunnen onafhankelijk van elkaar werken. Dit draagt bij aan het verhogen van de fouttolerantie van de applicatie, zodat fouten of crashes in een AppDomain geen invloed hebben op de rest van de applicatie.
AppDomains kunnen ook afzonderlijk geconfigureerd worden met verschillende beveiligingsniveaus. Dit kan de veiligheid van de applicatie verhogen door potentiële onveilige code te isoleren. Het kleine nadeel is dat de ontwikkelaar de applicatie zelf in subdomeinen moet splitsen, aangezien dit niet door de CLR wordt gedaan.
Klassebibliotheken
Het .NET Framework bevat een set van standaard klassebibliotheken. Een klassebibliotheek is georganiseerd in een hiërarchie van de namespace. De meeste ingebouwde API's maken deel uit van de Microsoft-namespace of de System-namespace. Deze klassebibliotheken implementeren een groot aantal gemeenschappelijke functies, zoals een bestand lezen en schrijven, grafische rendering, interactie met de database en manipulatie van XML-documenten. De .NET-klassebibliotheken zijn beschikbaar voor alle door de CLI gebruikte talen. De .NET Framework-klassebibliotheek is in tweeën opgedeeld: de Base Class Library en de Framework Class Library.
De Base Class Library (BCL) bevat een kleine deelverzameling van de hele klassebibliotheek en is de kern van de klassen die dienen als de basis-API van de Common Language Runtime. De klassen in mscorlib.dll en enkele van de klassen in System.dll en System.Core.dll worden beschouwd als een deel van de BCL. De BCL-klassen zijn beschikbaar in zowel het .NET Framework als zijn alternatieve implementaties inclusief .NET Compact Framework, Microsoft Silverlight en Mono.
Het Framework Class Library (FCL) is een superset van de BCL-klassen en verwijst naar de hele klassebibliotheek die bij het .NET Framework zit. Het bevat een uitgebreide set van library's, met daarbij inbegrepen de Windows Forms, ADO.NET, ASP.NET, Language Integrated Query, Windows Presentation Foundation en Windows Communication Foundation. De FCL is veel groter in omvang dan de standaard library's voor talen als C++, en vergelijkbaar in omvang met de standaard library's van Java.
Geheugenbeheer
De .NET Framework Common Language Runtime bevrijdt de ontwikkelaar van het geheugenbeheer (toewijzen en vrijmaken als je klaar bent); in plaats daarvan doet de CLR het geheugenbeheer zelf. Het geheugen dat toegewezen wordt aan instanties van .NET-klassen komt aaneengesloten uit de managed heap, een pool van geheugen die wordt beheerd door de CLR. Zolang er een verwijzing naar een object bestaat, die ofwel een directe verwijzing is, ofwel een verwijzing via een graaf van objecten, wordt het door de CLR gezien als in gebruik. Als er geen verwijzing naar een object is, kan het niet worden bereikt of gebruikt en wordt het 'garbage' ('afval'). Maar er is nog steeds geheugen aan toegewezen. .NET Framework bevat een 'garbage collector' die periodiek wordt uitgevoerd, op een aparte thread van de draad van de applicatie. Deze maakt een opsomming van alle ongebruikte objecten en geeft het geheugen dat daaraan toegewezen was weer vrij.
De .NET Garbage Collector (GC) is een non-deterministische, compacte, markeer-en-veeg-garbage collector. De GC draait alleen wanneer een bepaalde hoeveelheid geheugen in gebruik is of als er een nieuw object gecreëerd moet worden en er daarvoor onvoldoende ruimte is op de managed heap. Aangezien niet te voorspellen is wanneer de voorwaarden voor het hergebruiken van geheugen bereikt worden, wordt de GC niet-deterministisch genoemd. Elke .NET-applicatie heeft een set van wortels, die verwijzen naar objecten op de managed heap (beheerde objecten). Deze bevatten verwijzingen naar statische objecten en objecten gedefinieerd als lokale variabelen of methodeparameters in de huidige scope, evenals objecten waarnaar door CPU-registers wordt verwezen. Als de GC wordt uitgevoerd, pauzeert deze de applicatie, en somt voor elk object in de root, recursief alle objecten op die vanuit die root te bereiken zijn en markeert deze objecten als bereikbaar. Het gebruikt .NET-metadata en reflection om de objecten binnen een object te ontdekken en er dan recursief erdoorheen te lopen.
Vervolgens loopt het alle objecten op de heap af met behulp van reflection en test ook die op bereikbaarheid. Alle objecten gemarkeerd als niet bereikbaar zijn 'garbage'. Dit is de markeerfase. Omdat het geheugen dat wordt gebruikt door garbage van geen enkel belang is, wordt het gezien als vrije ruimte die kan worden hergebruikt. De GC zou in dit stadium kunnen stoppen en de applicatie hervatten. Echter, dat zou er toe leiden dat de global heap niet meer bestaat uit één stuk vrije ruimte, maar in plaats daarvan uit kleinere stukken vrije ruimte onderbroken door bereikbare objecten. Een gevolg kan zijn dat de CLR, wanneer een applicatie een object wil creëren, niet een groot genoeg geheugenblok beschikbaar heeft, hoewel alle beschikbare geheugenblokken bij elkaar wél groot genoeg zijn. Deze zogeheten fragmentatie wordt voorkomen omdat de GC alle bereikbare objecten zodanig verplaatst dat er één, ononderbroken, blok vrije ruimte op de managed heap ontstaat. Tot slot worden de verwijzingen naar de verplaatste objecten gevuld met de nieuwe locatie, waarna de applicatie wordt hervat.
Omdat een GC de applicatie onderbreekt moet dit proces zo kort mogelijk duren, zodat de gebruiker hier zo weinig mogelijk of niets van merkt. Hiertoe bevat de GC een optimalisatie, die ervoor zorgt dat niet elke keer alle objecten geïnspecteerd worden op bereikbaarheid. Aan objecten wordt een generatiegetal toegekend: aan nieuwe objecten wordt generatie 0 toegekend; objecten die een eerste garbage collection overleven worden generatie 1. Generatie 1-objecten die een volgende garbage collection overleven, worden generatie 2-objecten. Het .NET-framework nummert objecten tot generatie 2. De optimalisatie bestaat eruit dat objecten van een hogere generatie minder vaak aan GC worden onderworpen dan objecten van een lagere generatie. De GC stopt zodra voldoende geheugen is vrijgemaakt om aan de vraag hiernaar, die leidde tot de start van de GC, te voldoen.
Er wordt gewerkt aan twee alternatieve open source-implementaties van .NET, die kunnen geïnstalleerd worden op andere platformen, zoals Linux- en FreeBSD: