닷넷 프레임워크는 마이크로소프트에서 발표한 개발 환경이다. 일종의 가상 머신으로 닷넷 호환 언어로 작성된 프로그램은 닷넷 프레임워크가 설치된 환경에서만 작동할 수 있게 된다.
윈도우의 실행 파일인 EXE/DLL 파일은 닷넷 프레임워크 환경에서 만들어지는 경우, CLR(Common Language Runtime)이라고 하는 가상 머신에 의해 실행되며, CLR은 프로그램에 포함되어 있는 중간 언어를 CPU가 읽고 실행할 수 있는 기계어로 변환해주는 역할을 수행하게 된다.
닷넷 호환 언어의 관점(C# 기준)에서는 C# 컴파일러가 컴파일을 통해 C# 소스코드를 중간 언어로 만들고, 프로그램이 처음 실행되는 순간에 CLR을 로드하게 만드는 코드를 EXE/DLL 파일 내부에 생성하게 된다. 이것을 통해 프로그램이 실행되면 내부적으로 CLR이 먼저 로드되고, CLR은 EXE/DLL 파일 내부에 있는 중간 언어를 읽으면서 프로그램이 본격적인 실행 단계에 들어가게 된다.
공용 타입 시스템은 닷넷 호환 언어가 지켜야 할 타입의 표준 규격을 정의한 것이다. 예를 들어, 공용 타입 시스템에서 클래스 상속을 하나만 받을 수 있도록 정의한다면, 직접 닷넷 호환 언어를 만들 때 클래스의 다중 상속을 지원하도록 만들 수 없는 것이다. 따라서 닷넷 호환 언어는 공용 타입 시스템의 한계를 넘어서 구현할 수 없다. 하지만 공용 타입 시스템의 모든 규격을 구현할 필요는 없다.
공용 언어 사양은 닷넷 호환 언어가 지켜야 할 최소한의 언어 사양을 정의한 것이다. 공용 타입 시스템은 언어 스펙 확장의 경계선 역할을 하지만, 공용 언어 사양은 모든 닷넷 호환 언어가 지켜야 할 최소한의 사양이기 때문에 공용 언어 사양에 명시된 사양은 완벽하게 구현할 필요가 있다.
닷넷 호환 언어끼리 서로 사용/상속이 가능하다는 점을 생각해보면 공용 언어 사양을 통해 서로 다른 언어 간 호환성을 보증해주는 역할을 하게 되는 것이다.
닷넷 프레임워크의 CLR을 통해 동작하는 실행 파일은 완전하게 자기 서술적(self-descriptive)인 메타데이터를 제공하며, 외부에서는 이 정보를 리플렉션(reflection)이라는 기술을 통해 사용할 수 있다. 따라서 직접 닷넷 호환 언어를 만들어 컴파일러를 제공한다면 중간 언어는 물론이고 그에 대한 메타데이터도 함께 생성되게 만들어야 한다.
C#으로 프로그램을 만드는 경우 보통 EXE/DLL 파일을 만들게 된다. 닷넷에서는 이런 실행 파일을 어셈블리(assembly)라고 부른다. 기계어와 대응되는 어셈블리어와 이름이 같지만 닷넷에서는 실행 파일(EXE/DLL)을 의미한다는 것을 주의하자.
어셈블리, 즉, 닷넷에서 실행 파일은 1개 이상의 모듈(Module)로 구성된다. 이때 모듈 하나당 한 개의 파일이 대응된다. 그런데 여러 개의 파일, 다시 말해 여러 개의 모듈이 하나의 어셈블리(=실행파일)을 구성하고 있다면 그 목록을 관리하는 데이터가 있어야 한다. 따라서 여러 개의 모듈 중 하나는 반드시 다른 모듈 목록을 관리하는 매니페스트(Manifest)라는 데이터를 가지고 있어야 한다.
매니페스트를 포함하고 있지 않은 모듈은 보통 확장자가 netmodule이고, 매니페스트를 포함하는 경우에는 확장자가 DLL/EXE이다. 어셈블리는 그 자체가 '참조 단위'이자 '배포 단위'라는 것에 의미가 있다. 다른 사람이 만든 어셈블리에 구현된 코드를 사용하고 싶다면 매니페스트가 포함된 모듈 및 그와 관련된 모든 모듈을 함께 가지고 있어야 한다.
하지만 일반적으로 거의 모든 어셈블리는 하나의 모듈로 구성된다. 비주얼 스튜디오에서도 모듈 생성을 지원하지 않기 때문에 다중 모듈을 사용하는 경우는 거의 없다.
공용 언어 기반구조는 공용 타입 시스템(CTS) 명세를 포함하여, 중간 언어에 대한 코드 정의, 메타데이터와 그것을 포함하는 바이너리 파일의 구조까지 표준 사양으로 기술한 ECMA 표준 공개 규약이다.
자바의 VM을 IBM과 오라클에서 구현한 것처럼, 마이크로소프트에서 공개한 CLI 사양만 지킨다면 누구든지 임의로 CLI 구현체를 구현할 수 있다. 또한, CLI 구현체끼린 서로 호환이 가능하다.
우리가 지금까지 가상 머신이라고 부르던 CLR은 마이크로소프트가 직접 구현한 CLI의 구현체이다. CLR은 JIT 컴파일러 기능과 가비지 콜렉션 기능을 제공하고 있다. 또한, CLR은 실행 파일 내에서 공개된 API에 의해 로드될 수 있는 특징을 가지고 있다. 즉, 네이티브 언어로 작성된 어플리케이션에 CLR을 내장하여 사용이 가능하다는 것이다.
닷넷 프레임워크는 CLR에 더해 여러 가지 구성 요소를 함께 만들어 하나의 패키지로 묶어 배포한 것을 의미한다. 따라서 닷넷 프레임워크를 보다 세부적으로 정의하면 CLR + 기타 부가 구성 요소로 정의할 수 있고, 부가 구성 요소에는 다음과 같은 항목이 포함된다.
BCL(Base Class Library) : 특정 기능을 수행하는 타입
부가적인 실행 파일 : MS는 닷넷 프레임워크에 기본적으로 C#, VB 컴파일러를 제공하며, 각종 유틸리티 성격의 실행 파일을 포함한다.
GAC(Global Assembly Cache) : GAC는 컴퓨터에서 실행되는 닷넷 응용 프로그램이 어셈블리 파일을 찾을 수 있는 공용 전역 저장소이다.
CLI, CLR, 닷넷은 보통 구분 없이 사용하기 때문에 명확한 구분을 하기 위해서는 주의를 요한다.