참조 어셈블리 는 라이브러리의 공용 API 화면을 나타내는 데 필요한 최소 양의 메타데이터만 포함하는 특수 형식의 어셈블리입니다. 빌드 도구에서 어셈블리를 참조할 때 중요한 모든 멤버에 대한 선언을 포함하지만, 해당 API 계약에 영향을 미치지 않는 프라이빗 멤버의 선언과 모든 멤버 구현은 제외됩니다. 반면, 일반 어셈블리를 구현 어셈블리라고합니다.
참조 어셈블리는 실행을 위해 로드할 수 없지만 구현 어셈블리와 동일한 방식으로 컴파일러 입력으로 전달될 수 있습니다. 참조 어셈블리는 일반적으로 특정 플랫폼 또는 라이브러리의 SDK(소프트웨어 개발 키트)와 함께 배포됩니다.
참조 어셈블리를 사용하면 개발자가 해당 버전에 대한 전체 구현 어셈블리 없이 특정 라이브러리 버전을 대상으로 하는 프로그램을 빌드할 수 있습니다. 컴퓨터에 일부 라이브러리의 최신 버전만 있지만 해당 라이브러리의 이전 버전을 대상으로 하는 프로그램을 빌드하려고 합니다. 구현 어셈블리에 대해 직접 컴파일하는 경우 이전 버전에서 사용할 수 없는 API 멤버를 실수로 사용할 수 있습니다. 대상 컴퓨터에서 프로그램을 테스트할 때만 이 실수를 발견할 수 있습니다. 이전 버전의 참조 어셈블리에 대해 컴파일하는 경우 컴파일 시간 오류가 즉시 발생합니다.
참조 어셈블리는 구체적인 구현 어셈블리에 해당하지 않는 API 집합인 계약을 나타낼 수도 있습니다. 계약 어셈블리라고 하는 이러한 참조 어셈블리를 사용하여 동일한 API 집합을 지원하는 여러 플랫폼을 대상으로 지정할 수 있습니다. 예를 들어, .NET Standard는 서로 다른 .NET 플랫폼 간에 공유되는 공통 API 집합을 나타내는 계약 어셈블리 netstandard.dll를 제공합니다. 이러한 API의 구현은 .NET Framework의mscorlib.dll또는 .NET Core 의System.Private.CoreLib.dll 같은 여러 플랫폼의 다양한 어셈블리에 포함되어 있습니다. .NET Standard를 대상으로 하는 라이브러리는 .NET Standard를 지원하는 모든 플랫폼에서 실행할 수 있습니다.
참조 어셈블리 사용
프로젝트에서 특정 API를 사용하려면 해당 어셈블리에 참조를 추가해야 합니다. 구현 어셈블리 또는 참조 어셈블리에 대한 참조를 추가할 수 있습니다. 참조 어셈블리를 사용할 수 있을 때마다 사용하는 것이 좋습니다. 이렇게 하면 API 디자이너에서 사용하기 위해 대상 버전에서 지원되는 API 멤버만 사용하게 됩니다. 참조 어셈블리를 사용하면 구현 세부 정보에 종속되지 않습니다.
.NET Framework 라이브러리에 대한 참조 어셈블리는 대상 지정 팩과 함께 배포됩니다. 독립 실행형 설치 관리자를 다운로드하거나 Visual Studio 설치 관리자에서 구성 요소를 선택하여 가져올 수 있습니다. 자세한 내용은 개발자용 .NET Framework 설치를 참조하세요. .NET Core 및 .NET Standard의 경우 참조 어셈블리는 필요에 따라(NuGet을 통해) 자동으로 다운로드되고 참조됩니다. .NET Core 3.0 이상의 경우 핵심 프레임워크에 대한 참조 어셈블리는 Microsoft.NETCore.App.Ref 패키지에 있습니다( Microsoft.NETCore.App 패키지는 3.0 이전 버전에 대신 사용됨).
참조 추가 대화 상자를 사용하여 Visual Studio에서 .NET Framework 어셈블리에 대한 참조를 추가하면 목록에서 어셈블리를 선택하고 Visual Studio는 프로젝트에서 선택한 대상 프레임워크 버전에 해당하는 참조 어셈블리를 자동으로 찾습니다.
참조 프로젝트 항목을 사용하여 MSBuild 프로젝트에 직접 참조를 추가하는 경우도 마찬가지입니다. 전체 파일 경로가 아닌 어셈블리 이름만 지정하면 됩니다. 컴파일러 옵션(-reference
및 Visual Basic)을 사용 하거나 Roslyn API의 메서드를 사용하여 Compilation.AddReferences 명령줄에서 이러한 어셈블리에 대한 참조를 추가하는 경우 올바른 대상 플랫폼 버전에 대한 참조 어셈블리 파일을 수동으로 지정해야 합니다. .NET Framework 참조 어셈블리 파일은 %ProgramFiles(x86)%\Reference Assemblies\Microsoft\Framework\.NETFramework 디렉터리에 위치해 있습니다. .NET Core의 경우, 프로젝트 속성을 로 설정하여 게시 작업이 대상 플랫폼의 참조 어셈블리를 출력 디렉터리의 PreserveCompilationContext
하위 디렉터리에 복사하도록 강제할 수 있습니다. 그런 다음 이러한 참조 어셈블리 파일을 컴파일러에 전달할 수 있습니다.
DependencyContext
을(를) 사용하여 Microsoft.Extensions.DependencyModel 패키지 내에서 경로를 찾는 데 도움이 될 수 있습니다.
구현이 없으므로 실행을 위해 참조 어셈블리를 로드할 수 없습니다. 이렇게 하려고 하면 System.BadImageFormatException가 발생합니다. 참조 어셈블리의 내용을 검사하려면 .NET Framework의 리플렉션 전용 컨텍스트에 Assembly.ReflectionOnlyLoad 메서드를 사용하여 로드하거나, .NET 및 .NET Framework에 MetadataLoadContext 를 사용할 수 있습니다.
참조 어셈블리 생성
라이브러리 소비자가 다양한 버전의 라이브러리에 대해 프로그램을 빌드해야 하는 경우 라이브러리에 대한 참조 어셈블리를 생성하는 것이 유용할 수 있습니다. 이러한 모든 버전에 대해 구현 어셈블리를 배포하는 것은 크기가 크기 때문에 실용적이지 않을 수 있습니다. 참조 어셈블리의 크기는 더 작으며 라이브러리 SDK의 일부로 배포하면 다운로드 크기가 줄어들고 디스크 공간이 절약됩니다.
또한 IDE 및 빌드 도구는 참조 어셈블리를 활용하여 여러 클래스 라이브러리로 구성된 대규모 솔루션의 경우 빌드 시간을 줄일 수 있습니다. 일반적으로 증분 빌드 시나리오에서 프로젝트는 의존하는 어셈블리를 포함하여 입력 파일이 변경될 때 다시 빌드됩니다. 프로그래머가 멤버의 구현을 변경할 때마다 구현 어셈블리가 변경됩니다. 참조 어셈블리는 공용 API가 영향을 받는 경우에만 변경됩니다. 따라서 참조 어셈블리를 구현 어셈블리 대신 입력 파일로 사용하면 경우에 따라 종속 프로젝트의 빌드를 건너뛸 수 있습니다.
참조 어셈블리를 생성할 수 있습니다.
- MSBuild 프로젝트에서 프로젝트 속성을 사용합니다
ProduceReferenceAssembly
. - 명령줄에서 프로그램을 컴파일할 때 (
-refonly
Visual Basic) 또는 / (C#-refout
/ ) 컴파일러 옵션을 지정합니다 . - Roslyn API를 사용할 때, EmitOptions.EmitMetadataOnly를
true
로 설정하고 EmitOptions.IncludePrivateMembers를false
로 설정하여 메서드에 전달된 Compilation.Emit 개체를 사용합니다.
NuGet 패키지를 사용하여 참조 어셈블리를 배포하려면 구현 어셈블리에 사용되는 lib\ 하위 디렉터리가 아닌 패키지 디렉터리 아래의 ref\ 하위 디렉터리에 포함해야 합니다.
참조 어셈블리 구조
참조 어셈블리는 관련 개념인 메타데이터 전용 어셈블리의 확장입니다. 메타데이터 전용 어셈블리에는 메서드 본문이 단일 throw null
본문으로 대체되지만 익명 형식을 제외한 모든 멤버가 포함됩니다. 본문이 없는 것과 달리 본문을 사용하는 throw null
이유는 PEVerify 를 실행하고 전달할 수 있기 때문입니다(따라서 메타데이터의 완전성 유효성 검사).
참조 어셈블리는 메타데이터 전용 어셈블리에서 메타데이터(프라이빗 멤버)를 추가로 제거합니다.
- 참조 어셈블리에는 API 화면에 필요한 내용에 대한 참조만 있습니다. 실제 어셈블리에는 특정 구현과 관련된 추가 참조가 있을 수 있습니다. 예를 들어,
class C { private void M() { dynamic d = 1; ... } }
에 대한 참조 어셈블리는dynamic
에 필요한 형식을 참조하지 않습니다. - 프라이빗 함수 멤버(메서드, 속성 및 이벤트)는 제거가 컴파일에 눈에 띄게 영향을 주지 않는 경우 제거됩니다. InternalsVisibleTo 특성이 없으면 내부 함수 멤버도 제거됩니다.
참조 어셈블리의 메타데이터는 다음 정보를 계속 유지합니다.
- 프라이빗 및 중첩 형식을 비롯한 모든 형식입니다.
- 모든 특성, 심지어 내부 특성까지.
- 모든 가상 메서드.
- 명시적 인터페이스 구현.
- 해당 접근자가 가상이기 때문에 명시적으로 구현된 속성 및 이벤트입니다.
- 구조체의 모든 필드입니다.
참조 어셈블리에는 어셈블리 수준 ReferenceAssembly 특성이 포함됩니다. 이 특성은 원본에서 지정할 수 있습니다. 그러면 컴파일러가 합성할 필요가 없습니다. 이 특성 때문에 런타임은 실행을 위해 참조 어셈블리 로드를 거부하지만 리플렉션 전용 모드에서 로드할 수 있습니다.
정확한 참조 어셈블리 구조 세부 정보는 컴파일러 버전에 따라 달라집니다. 최신 버전은 공용 API 화면에 영향을 주지 않는 것으로 판단되는 경우 더 많은 메타데이터를 제외하도록 선택할 수 있습니다.
비고
이 섹션의 정보는 C# 버전 7.1 또는 Visual Basic 버전 15.3부터 Roslyn 컴파일러에서 생성된 어셈블리를 참조하는 데만 적용됩니다. .NET Framework 및 .NET Core 라이브러리에 대한 참조 어셈블리의 구조는 참조 어셈블리를 생성하는 자체 메커니즘을 사용하므로 일부 세부 정보가 다를 수 있습니다. 예를 들어 그들은 throw null
본문 대신 메서드 본문이 완전히 비어 있을 수 있습니다. 그러나 일반적인 원칙은 여전히 적용됩니다. 사용 가능한 메서드 구현이 없으며 공용 API 관점에서 관찰 가능한 영향을 미치는 멤버에 대해서만 메타데이터를 포함합니다.
참고하십시오
.NET