리소스 패키징 및 배포
업데이트: 2007년 11월
.NET Framework에서는 허브와 스포크 모델을 사용하여 리소스를 패키징하고 배포합니다. 허브는 지역화할 수 없는 실행 코드와 중립 또는 기본 문화권이라고 하는 단일 문화권의 리소스를 포함하는 주 어셈블리입니다. 기본 문화권은 응용 프로그램의 대체 문화권입니다. 각 스포크는 단일 문화권의 리소스를 포함하지만 코드는 포함하지 않는 위성 어셈블리에 연결됩니다.
이 모델은 다음과 같은 몇 가지 장점을 가집니다.
응용 프로그램을 배포한 후 새 문화권에 대해 리소스를 점진적으로 추가할 수 있습니다. 문화권별 리소스의 다음 번 배포에는 상당한 시간이 필요하므로 이 모델을 사용하면 주 응용 프로그램을 먼저 릴리스하고 나중에 문화권별 리소스를 전달할 수 있습니다.
응용 프로그램을 다시 컴파일하지 않고 응용 프로그램의 위성 어셈블리를 업데이트 및 변경할 수 있습니다.
응용 프로그램은 특정 문화권에 필요한 리소스를 포함하는 위성 어셈블리만 로드해야 합니다. 이렇게 하면 시스템 리소스 사용을 상당히 줄일 수 있습니다.
그러나 다음과 같이 이 모델 사용에 따른 단점도 있습니다.
여러 개의 리소스 집합을 관리해야 합니다.
여러 개의 구성을 테스트해야 하므로 응용 프로그램 테스트의 초기 비용이 높습니다. 장기적으로 볼 때 여러 개의 동일한 국가별 버전을 테스트하고 유지 관리하는 것보다는 위성 어셈블리가 여러 개 있는 하나의 핵심 응용 프로그램을 테스트하는 것이 더 쉽고 비용도 적게 듭니다.
리소스 명명 규칙
응용 프로그램의 리소스를 패키지하는 경우 공용 언어 런타임에서 예상하는 리소스 명명 규칙을 사용하여 리소스 이름을 지정해야 합니다. 런타임에서는 문화권 서명 또는 이름으로 리소스를 식별합니다. 각 문화권에는 고유한 이름이 지정됩니다. 이 이름은 언어와 관련된 두 자의 소문자 문화권 이름과 필요한 경우 국가 또는 지역과 관련된 두 자의 대문자 하위 문화권 이름의 조합입니다. 하위 문화권 이름은 문화권 이름 뒤에 오며 대시(-)로 구분됩니다. 예를 들어 일본어(일본)는 ja-JP, 영어(미국)는 en-US, 독일어(독일)는 de-DE, 독일어(오스트리아)는 de-AT로 나타냅니다. 전체 문화권 이름 목록을 보려면 CultureInfo 클래스를 참조하십시오.
리소스 대체 프로세스
리소스 패키징 및 배포를 위한 허브와 스포크 모델은 대체 프로세스를 사용하여 적절한 리소스를 찾습니다. 사용할 수 없는 ResourceSet을 응용 프로그램 사용자가 요청하면 공용 언어 런타임에서 문화권 계층 구조를 검색하여 사용자의 요청과 가장 근접하게 일치하는 적절한 대체 리소스를 찾고, 이러한 대체 리소스가 없는 경우에만 예외를 발생시킵니다. 계층의 각 수준에서 적절한 리소스를 찾으면 런타임에서는 해당 리소스를 사용하고 리소스를 찾지 못하면 다음 수준에서 계속 검색합니다. 다음은 리소스 대체 프로세스에 대한 단계별 설명입니다.
런타임에서는 먼저 전역 어셈블리 캐시를 검사하여 응용 프로그램에 대해 요청된 문화권과 일치하는 어셈블리를 찾습니다.
전역 어셈블리 캐시는 여러 응용 프로그램에서 공유하는 리소스 어셈블리를 저장할 수 있습니다. 이렇게 하면 사용자가 만드는 모든 응용 프로그램의 디렉터리 구조에 특정 리소스 집합을 포함할 필요가 없습니다. 런타임에서 어셈블리에 대한 참조를 찾으면 요청된 리소스가 있는지 해당 어셈블리를 검색합니다. 어셈블리에서 엔트리를 찾으면 요청된 리소스를 사용하고 엔트리를 찾지 못하면 검색을 계속합니다.
그런 다음 런타임에서는 현재 실행 중인 어셈블리의 디렉터리를 검사하여 요청된 문화권과 일치하는 디렉터리인지 확인합니다. 디렉터리를 찾으면 요청된 문화권에 대해 올바른 위성 어셈블리가 있는지 해당 디렉터리를 검색합니다. 그런 다음 런타임에서는 요청된 리소스가 있는지 위성 어셈블리를 검색합니다. 어셈블리에서 리소스를 찾으면 이것을 사용하고 리소스를 찾지 못하면 검색을 계속합니다.
그런 다음 런타임에서는 다시 전역 어셈블리 캐시를 검색하는데 이번에는 요청된 리소스의 부모 어셈블리를 찾습니다. 전역 어셈블리 캐시에 부모 어셈블리가 있으면 런타임에서는 요청된 리소스가 있는지 어셈블리를 검색합니다.
부모는 적절한 대체 문화권으로 정의됩니다. 부모 어셈블리를 가장 적합한 후보로 고려하십시오. 어떤 것이든 리소스를 제공하는 것이 예외를 throw하는 것보다는 좋습니다. 또한 이 프로세스를 사용하면 리소스를 다시 사용할 수 있습니다. 자식 문화권에서 요청된 리소스를 지역화할 필요가 없는 경우에만 부모 수준에서 특정 리소스를 포함해야 합니다. 예를 들어 en(중립 영어), en-GB(영국식 영어) 및 en-US(미국식 영어)에 대해 위성 어셈블리를 제공하면 en 위성은 공용 용어를 포함하고 en-GB와 en-US 위성은 그 외의 다른 용어에 대해서만 재정의할 수 있습니다.
그런 다음 런타임에서는 현재 실행 중인 어셈블리의 디렉터리를 검사하여 부모 디렉터리를 포함하는지 확인합니다. 부모 디렉터리가 있으면 런타임에서는 부모 문화권에 대해 올바른 위성 어셈블리가 있는지 해당 디렉터리를 검색합니다. 어셈블리를 찾으면 런타임에서는 요청된 리소스가 있는지 해당 어셈블리를 검색합니다. 리소스를 찾으면 이것을 사용하고 리소스를 찾지 못하면 검색을 계속합니다.
그런 다음 런타임에서는 이전 단계에서와 같이 가능한 여러 수준에서 부모 어셈블리를 검색합니다. 각 문화권에는 부모가 하나뿐이지만 부모는 자신의 부모를 가질 수 있습니다.
처음에 지정된 문화권과 모든 부모를 검색한 결과 리소스를 찾지 못한 경우 기본(대체) 문화권의 리소스가 사용됩니다. .NET Framework 버전 2.0 릴리스부터는 리소스의 최종 대체(fallback) 위치가 주 어셈블리가 아닌 위성 어셈블리가 되도록 지정할 수 있습니다. NeutralResourcesLanguageAttribute에 UltimateResourceFallbackLocation 열거형을 사용하면 리소스의 최종 대체(fallback) 위치가 주 어셈블리인지 아니면 위성 어셈블리인지를 제어할 수 있습니다.
참고: 기본 리소스는 주 어셈블리와 함께 컴파일된 리소스뿐입니다. Unless you specify a satellite assembly using the NeutralResourcesLanguageAttribute를 사용하여 위성 어셈블리를 지정하지 않으면 기본 리소스가 최종 대체(최종 부모)가 됩니다. 주 어셈블리에 항상 기본 리소스 집합을 포함하는 것이 좋습니다. 이렇게 하면 예외가 throw되지 않습니다. 기본 리소스 파일을 포함시킴으로써, 사용자를 위한 적어도 하나 이상의 리소스(특정 문화권에 관련되지는 않음)가 항상 있도록 모든 리소스에 대한 대체를 제공할 수 있습니다.
마지막으로, 런타임에서 기본(대체) 문화권의 리소스를 찾지 못하면 예외가 throw되어 리소스를 찾을 수 없음을 나타냅니다.
요청된 리소스를 검색하는 방법에 대한 예로서, 스페인어(멕시코)에 대해 지역화된 리소스를 요청하는 경우를 가정해 봅니다. 앞에서 설명한 리소스 명명 규칙에 따라 런타임에서는 먼저 요청된 문화권, "es-MX"와 일치하는 어셈블리가 있는지 전역 어셈블리 캐시를 검색합니다. 찾지 못하면 런타임에서는 현재 실행 중인 어셈블리의 디렉터리에서 "es-MX" 디렉터리를 검색합니다. 실패하면 런타임에서는 전역 어셈블리 캐시를 다시 검색하여 적절한 대체 문화권, 여기에서는 "es"(스페인어)를 반영하는 부모 어셈블리를 찾습니다. 부모 어셈블리를 찾지 못하면 부모 어셈블리의 가능한 모든 수준을 검색하여 해당하는 리소스를 찾을 때까지 "es-MX" 문화권을 찾습니다. 리소스를 찾지 못하면 런타임에서는 기본 문화권의 리소스를 사용합니다.
최종 대체(Fallback)를 위성 어셈블리로
.NET Framework 버전 2.0 릴리스부터는 선택적으로 주 어셈블리에서 리소스를 제거하고 최종 대체(fallback) 리소스가 특정 문화권에 해당하는 위성 어셈블리에 있도록 지정할 수 있습니다. 대체 프로세스를 제어하려면 NeutralResourcesLanguageAttribute를 사용합니다. UltimateResourceFallbackLocation 매개 변수를 추가로 받는 새로운 생성자가 NeutralResourcesLanguageAttribute 클래스에 추가되었습니다. 이 매개 변수에 ResourceManager가 대체 리소스를 추출할 위치(주 어셈블리 또는 위성 어셈블리)를 지정할 수 있습니다.
다음 예제에서는 클래스 수준에서 특성을 적용하는 방법을 보여 줍니다.
[assembly: NeutralResourcesLanguageAttribute("de" , UltimateResourceFallbackLocation.Satellite)]
이렇게 하면 ResourceManager에서는 최종 대체(fallback) 위치로 현재 실행 중인 어셈블리 디렉터리의 "de" 하위 디렉터리에서 리소스를 찾습니다.
패키징 대체 방법 제안
시간이나 예산 제약 조건으로 인해 응용 프로그램에서 지원하는 모든 하위 문화권의 리소스 집합을 만들지 못할 수도 있습니다. 이런 경우 관련된 모든 하위 문화권에서 사용할 수 있는 부모 문화권에 대한 단일 위성 어셈블리를 만들 수 있습니다. 예를 들어 국가별 영어 리소스를 요청하는 사용자에 의해 검색되는 영어 위성 어셈블리(en) 하나와 국가별 독일어 리소스를 요청하는 사용자를 위해 독일어 위성 어셈블리(de) 하나를 제공할 수 있습니다. 예를 들어 독일에서 사용하는 독일어(de-DE), 오스트리아에서 사용하는 독일어(de-AT) 및 스위스에서 사용하는 독일어(de-CH)를 요청하면 독일어 위성 어셈블리(de)로 대체됩니다. 주 어셈블리와 함께 컴파일할 기본 어셈블리를 선택할 때는 주의해야 합니다. 기본 리소스는 마지막 대체이므로 대부분의 응용 프로그램 사용자가 요청하는 리소스여야 합니다. 이 방법을 사용하면 문화권에 특정하지 않은 리소스가 배포된다 하더라도 응용 프로그램의 지역화 비용을 상당히 줄일 수 있습니다.