.NET 앱에서 리소스 패키징 및 배포Packaging and Deploying Resources in .NET Apps

애플리케이션은 ResourceManager 클래스가 나타내는 .NET Framework 리소스 관리자를 사용하여 지역화된 리소스를 검색합니다.Applications rely on the .NET Framework Resource Manager, represented by the ResourceManager class, to retrieve localized resources. 리소스 관리자는 허브 및 스포크 모델이 리소스 패키지 및 배포에 사용된다고 가정합니다.The Resource Manager assumes that a hub and spoke model is used to package and deploy resources. 허브는 지역화할 수 없는 실행 코드와 중립 또는 기본 문화권이라고 하는 단일 문화권의 리소스를 포함하는 주 어셈블리입니다.The hub is the main assembly that contains the nonlocalizable executable code and the resources for a single culture, called the neutral or default culture. 기본 문화권은 애플리케이션의 대체 문화권으로, 지역화된 리소스를 찾을 수 없는 경우 해당 리소스가 사용되는 문화권입니다.The default culture is the fallback culture for the application; it is the culture whose resources are used if localized resources cannot be found. 각 스포크는 단일 문화권의 리소스를 포함하지만 코드는 포함하지 않는 위성 어셈블리에 연결됩니다.Each spoke connects to a satellite assembly that contains the resources for a single culture, but does not contain any code.

이 모델에는 다음과 같은 몇 가지 이점이 있습니다.There are several advantages to this model:

  • 애플리케이션을 배포한 후 새로운 문화권에 대한 리소스를 증분 방식으로 추가할 수 있습니다.You can incrementally add resources for new cultures after you have deployed an application. 문화권 관련 리소스의 후속 개발에 상당한 시간이 필요할 수 있기 때문에 주 애플리케이션을 먼저 릴리스한 다음 나중에 문화권 관련 리소스를 제공할 수 있습니다.Because subsequent development of culture-specific resources can require a significant amount of time, this allows you to release your main application first, and deliver culture-specific resources at a later date.
  • 애플리케이션을 다시 컴파일하지 않고 애플리케이션의 위성 어셈블리를 업데이트하고 변경할 수 있습니다.You can update and change an application's satellite assemblies without recompiling the application.
  • 애플리케이션은 특정 문화권에 필요한 리소스를 포함하는 위성 어셈블리만 로드해야 합니다.An application needs to load only those satellite assemblies that contain the resources needed for a particular culture. 이렇게 하면 시스템 리소스의 사용을 훨씬 줄일 수 있습니다.This can significantly reduce the use of system resources.

그러나 이 모델에는 다음과 같은 단점도 있습니다.However, there are also disadvantages to this model:

  • 여러 개의 리소스 집합을 관리해야 합니다.You must manage multiple sets of resources.
  • 여러 구성을 테스트해야 하기 때문에 애플리케이션을 테스트하는 초기 비용이 증가합니다.The initial cost of testing an application increases, because you must test several configurations. 장기적으로는 여러 개의 병렬 국제 버전을 테스트 및 유지 관리하는 것보다 여러 개의 위성 어셈블리가 있는 핵심 애플리케이션 하나를 테스트하는 것이 더 쉽고 저렴합니다.Note that in the long term it will be easier and less expensive to test one core application with several satellites, than to test and maintain several parallel international versions.

리소스 명명 규칙Resource naming conventions

애플리케이션의 리소스를 패키지할 때는 공용 언어 런타임에서 적용하는 리소스 명명 규칙을 사용하여 이름을 지정해야 합니다.When you package your application's resources, you must name them using the resource naming conventions that the common language runtime expects. 런타임에서는 문화권 이름으로 리소스를 식별합니다.The runtime identifies a resource by its culture name. 각 문화권에는 일반적으로 언어와 관련된 2자의 소문자 문화권 이름과 필요한 경우 국가 또는 지역과 관련된 2자의 대문자 하위 문화권 이름이 조합된 고유한 이름이 지정됩니다.Each culture is given a unique name, which is usually a combination of a two-letter, lowercase culture name associated with a language and, if required, a two-letter, uppercase subculture name associated with a country or region. 하위 문화권 이름이 문화권 이름 다음에 추가되고 대시(-)로 구분됩니다.The subculture name follows the culture name, separated by a dash (-). 예를 들어 일본에서 사용되는 일본어는 ja-JP, 미국에서 사용되는 영어는 en-US, 독일에서 사용되는 독일어는 de-DE, 오스트리아에서 사용되는 독일어는 de-AT입니다.Examples include ja-JP for Japanese as spoken in Japan, en-US for English as spoken in the United States, de-DE for German as spoken in Germany, or de-AT for German as spoken in Austria. Windows에서 지원하는 언어/지역 이름 목록언어 태그 열을 참조하세요.See the Language tag column in the list of language/region names supported by Windows. 문화권 이름은 BCP 47에 정의된 표준을 따릅니다.Culture names follow the standard defined by BCP 47.

참고

중국어(간체)의 경우 zh-Hans와 같이 두 문자로 된 문화권 이름에 대한 몇 가지 예외가 있습니다.There are some exceptions for the two-letter culture names, such as zh-Hans for Chinese (Simplified).

참고

리소스 파일을 만드는 방법에 대한 자세한 내용은 리소스 파일 만들기위성 어셈블리 만들기를 참조하세요.For information about creating resource files, see Creating Resource Files and Creating Satellite Assemblies.

리소스 대체 프로세스The Resource Fallback Process

리소스를 패키지 및 배포하는 분산형 모델에서는 대체 프로세스를 통해 적절한 리소스를 찾습니다.The hub and spoke model for packaging and deploying resources uses a fallback process to locate appropriate resources. 애플리케이션이 사용할 수 없는 지역화된 리소스를 요청할 경우 공용 언어 런타임은 문화권 계층 구조에서 사용자의 애플리케이션 요청과 가장 일치하는 적절한 대체 리소스를 검색하며, 어떠한 리소스도 찾을 수 없을 때만 예외를 throw합니다.If an application requests a localized resource that is unavailable, the common language runtime searches the hierarchy of cultures for an appropriate fallback resource that most closely matches the user's application's request, and throws an exception only as a last resort. 계층 구조의 각 수준에서 적절한 리소스가 발견되면 런타임에서 해당 리소스를 사용합니다.At each level of the hierarchy, if an appropriate resource is found, the runtime uses it. 리소스가 발견되지 않으면 검색이 다음 수준으로 진행됩니다.If the resource is not found, the search continues at the next level.

조회 성능을 향상하려면 주 어셈블리에 NeutralResourcesLanguageAttribute 특성을 적용하고 주 어셈블리에서 작동하는 중립 언어의 이름을 전달합니다.To improve lookup performance, apply the NeutralResourcesLanguageAttribute attribute to your main assembly, and pass it the name of the neutral language that will work with your main assembly.

.NET Framework 리소스 대체 프로세스.NET Framework resource fallback process

.NET Framework 리소스 대체 프로세스에는 다음 단계가 포함됩니다.The .NET Framework resource fallback process involves the following steps:

<relativeBindForResources> 구성 요소를 사용하여 런타임이 리소스 어셈블리를 검색하는 프로세스 및 리소스 대체 프로세스를 최적화할 수도 있습니다.You may be able to use the <relativeBindForResources> configuration element to optimize the resource fallback process and the process by which the runtime probes for resource assemblies. 자세한 내용은 리소스 대체 프로세스 최적화 섹션을 참조하세요.For more information, see the Optimizing the Resource Fallback Process section.

  1. 런타임은 먼저 전역 어셈블리 캐시에서 애플리케이션에 대해 요청된 문화권과 일치하는 어셈블리를 확인합니다.The runtime first checks the global assembly cache for an assembly that matches the requested culture for your application.

    전역 어셈블리 캐시는 많은 애플리케이션이 공유하는 리소스 어셈블리를 저장할 수 있습니다.The global assembly cache can store resource assemblies that are shared by many applications. 이렇게 하면 만드는 모든 애플리케이션의 디렉터리 구조에 특정 리소스 집합을 포함할 필요가 없습니다.This frees you from having to include specific sets of resources in the directory structure of every application you create. 런타임은 어셈블리에 대한 참조를 발견할 경우 어셈블리에서 요청된 리소스를 검색합니다.If the runtime finds a reference to the assembly, it searches the assembly for the requested resource. 어셈블리에서 항목을 찾으면 요청된 리소스가 사용됩니다.If it finds the entry in the assembly, it uses the requested resource. 항목을 찾지 못하면 검색을 계속합니다.If it doesn't find the entry, it continues the search.

  2. 그런 다음, 런타임은 현재 실행 중인 어셈블리의 디렉터리에서 요청된 문화권과 일치하는 하위 디렉터리를 확인합니다.The runtime next checks the directory of the currently executing assembly for a subdirectory that matches the requested culture. 하위 디렉터리를 찾으면 해당 하위 디렉터리에서 요청된 문화권에 유효한 위성 어셈블리를 검색합니다.If it finds the subdirectory, it searches that subdirectory for a valid satellite assembly for the requested culture. 그다음 런타임은 위성 어셈블리에서 요청된 리소스를 검색합니다.The runtime then searches the satellite assembly for the requested resource. 어셈블리에서 리소스를 찾으면 해당 리소스가 사용됩니다.If it finds the resource in the assembly, it uses it. 리소스를 찾지 못하면 검색을 계속합니다.If it doesn't find the resource, it continues the search.

  3. 그다음 런타임은 Windows Installer를 쿼리하여 요청 시 위성 어셈블리를 설치할지 여부를 확인합니다.The runtime next queries the Windows Installer to determine whether the satellite assembly is to be installed on demand. 설치할 경우 설치를 처리하고, 어셈블리를 로드한 다음 어셈블리나 요청된 리소스를 검색합니다.If so, it handles the installation, loads the assembly, and searches it or the requested resource. 어셈블리에서 리소스를 찾으면 해당 리소스가 사용됩니다.If it finds the resource in the assembly, it uses it. 리소스를 찾지 못하면 검색을 계속합니다.If it doesn't find the resource, it continues the search.

  4. 런타임은 AppDomain.AssemblyResolve 이벤트를 발생시켜 위성 어셈블리를 찾을 수 없음을 나타냅니다.The runtime raises the AppDomain.AssemblyResolve event to indicate that it is unable to find the satellite assembly. 이벤트를 처리하도록 선택한 경우 이벤트 처리기에서 조회에 해당 리소스가 사용되는 위성 어셈블리에 대한 참조를 반환할 수 있습니다.If you choose to handle the event, your event handler can return a reference to the satellite assembly whose resources will be used for the lookup. 이벤트를 처리하지 않는 경우 이벤트 처리기에서 null을 반환하고 검색이 계속됩니다.Otherwise, the event handler returns null and the search continues.

  5. 그다음 런타임은 전역 어셈블리 캐시에서 이번에는 요청된 문화권의 부모 어셈블리를 검색합니다.The runtime next searches the global assembly cache again, this time for the parent assembly of the requested culture. 부모 어셈블리가 전역 어셈블리 캐시에 있을 경우 런타임은 어셈블리에서 요청된 리소스를 검색합니다.If the parent assembly exists in the global assembly cache, the runtime searches the assembly for the requested resource.

    부모 문화권은 적절한 대체 문화권으로 정의됩니다.The parent culture is defined as the appropriate fallback culture. 리소스를 제공하는 것이 예외를 throw하는 것보다 낫기 때문에 부모를 대체 후보로 고려합니다.Consider parents as fallback candidates, because providing any resource is preferable to throwing an exception. 이 프로세스를 통해 리소스를 다시 사용할 수도 있습니다.This process also allows you to reuse resources. 자식 문화권이 요청된 리소스를 지역화할 필요가 없는 경우에만 부모 수준에 특정 리소스를 포함해야 합니다.You should include a particular resource at the parent level only if the child culture doesn't need to localize the requested resource. 예를 들어 en(중립 영어), en-GB(영국에서 사용되는 영어) 및 en-US(미국에서 사용되는 영어)에 대한 위성 어셈블리를 제공하는 경우 en 위성에 일반적인 용어가 포함되고, en-GBen-US 위성은 차이가 있는 용어에 대한 재정의만 제공할 수 있습니다.For example, if you supply satellite assemblies for en (neutral English), en-GB (English as spoken in the United Kingdom), and en-US (English as spoken in the United States), the en satellite would contain the common terminology, and the en-GB and en-US satellites could provide overrides for only those terms that differ.

  6. 그다음 런타임은 현재 실행 중인 어셈블리의 디렉터리를 검사하여 부모 디렉터리가 포함되어 있는지 확인합니다.The runtime next checks the directory of the currently executing assembly to see if it contains a parent directory. 부모 디렉터리가 있을 경우 런타임은 디렉터리에서 부모 문화권에 대한 유효한 위성 어셈블리를 검색합니다.If a parent directory exists, the runtime searches the directory for a valid satellite assembly for the parent culture. 런타임은 어셈블리를 발견할 경우 어셈블리에서 요청된 리소스를 검색합니다.If it finds the assembly, the runtime searches the assembly for the requested resource. 리소스를 찾으면 해당 리소스가 사용됩니다.If it finds the resource, it uses it. 리소스를 찾지 못하면 검색을 계속합니다.If it doesn't find the resource, it continues the search.

  7. 그다음 런타임은 Windows Installer를 쿼리하여 요청 시 부모 위성 어셈블리를 설치할지 여부를 확인합니다.The runtime next queries the Windows Installer to determine whether the parent satellite assembly is to be installed on demand. 설치할 경우 설치를 처리하고, 어셈블리를 로드한 다음 어셈블리나 요청된 리소스를 검색합니다.If so, it handles the installation, loads the assembly, and searches it or the requested resource. 어셈블리에서 리소스를 찾으면 해당 리소스가 사용됩니다.If it finds the resource in the assembly, it uses it. 리소스를 찾지 못하면 검색을 계속합니다.If it doesn't find the resource, it continues the search.

  8. 런타임은 AppDomain.AssemblyResolve 이벤트를 발생시켜 적절한 대체 리소스를 찾을 수 없음을 나타냅니다.The runtime raises the AppDomain.AssemblyResolve event to indicate that it is unable to find an appropriate fallback resource. 이벤트를 처리하도록 선택한 경우 이벤트 처리기에서 조회에 해당 리소스가 사용되는 위성 어셈블리에 대한 참조를 반환할 수 있습니다.If you choose to handle the event, your event handler can return a reference to the satellite assembly whose resources will be used for the lookup. 이벤트를 처리하지 않는 경우 이벤트 처리기에서 null을 반환하고 검색이 계속됩니다.Otherwise, the event handler returns null and the search continues.

  9. 그다음 런타임은 앞의 세 단계와 마찬가지로 가능한 여러 수준에서 부모 어셈블리를 검색합니다.The runtime next searches parent assemblies, as in the previous three steps, through many potential levels. 각 문화권에는 CultureInfo.Parent 속성으로 정의된 부모 하나만 있지만 부모가 해당 부모를 포함할 수도 있습니다.Each culture has only one parent, which is defined by the CultureInfo.Parent property, but a parent might have its own parent. 문화권의 Parent 속성이 CultureInfo.InvariantCulture을 반환하면 부모 문화권 검색이 중지됩니다. 리소스 대체에서 고정 문화권은 부모 문화권 또는 리소스를 가질 수 있는 문화권으로 간주되지 않습니다.The search for parent cultures stops when a culture's Parent property returns CultureInfo.InvariantCulture; for resource fallback, the invariant culture is not considered a parent culture or a culture that can have resources.

  10. 원래 지정된 문화권 및 모든 부모를 검색했지만 리소스를 찾지 못하면 기본(대체) 문화권의 리소스가 사용됩니다.If the culture that was originally specified and all parents have been searched and the resource is still not found, the resource for the default (fallback) culture is used. 일반적으로 기본 문화권의 리소스는 주 애플리케이션 어셈블리에 포함되어 있습니다.Typically, the resources for the default culture are included in the main application assembly. 그러나 NeutralResourcesLanguageAttribute 특성의 Location 속성에 대해 Satellite 값을 지정하여 리소스의 최종 대체 위치가 주 어셈블리가 아니라 위성 어셈블리임을 나타낼 수 있습니다.However, you can specify a value of Satellite for the Location property of the NeutralResourcesLanguageAttribute attribute to indicate that the ultimate fallback location for resources is a satellite assembly, rather than the main assembly.

    참고

    기본 리소스는 주 어셈블리와 함께 컴파일할 수 있는 유일한 리소스입니다.The default resource is the only resource that can be compiled with the main assembly. NeutralResourcesLanguageAttribute 특성을 사용하여 위성 어셈블리를 지정하지 않을 경우 이 리소스가 최종 대체(최종 부모)입니다.Unless you specify a satellite assembly by using the NeutralResourcesLanguageAttribute attribute, it is the ultimate fallback (final parent). 따라서 주 어셈블리에 기본 리소스 집합을 항상 포함하는 것이 좋습니다.Therefore, we recommend that you always include a default set of resources in your main assembly. 이렇게 하면 예외가 throw되지 않도록 방지하는 데 도움이 됩니다.This helps prevent exceptions from being thrown. 기본 리소스 파일을 포함하여 모든 리소스에 대한 대체를 제공하고 문화권별 리소스는 아니라도 사용자에게 항상 리소스가 하나 이상 제공되도록 합니다.By including a default resource, file you provide a fallback for all resources and ensure that at least one resource is always present for the user, even if it is not culturally specific.

  11. 마지막으로, 런타임이 기본(대체) 문화권의 리소스를 찾지 못하면 MissingManifestResourceException 또는 MissingSatelliteAssemblyException 예외가 throw되어 리소스를 찾을 수 없음을 나타냅니다.Finally, if the runtime doesn't find a resource for a default (fallback) culture, a MissingManifestResourceException or MissingSatelliteAssemblyException exception is thrown to indicate that the resource could not be found.

예를 들어 애플리케이션이 스페인어(멕시코)(es-MX 문화권)에 대해 지역화된 리소스를 요청한다고 가정해 보세요.For example, suppose the application requests a resource localized for Spanish (Mexico) (the es-MX culture). 런타임은 먼저 전역 어셈블리 캐시에서 es-MX와 일치하는 어셈블리를 검색하지만 찾지 못합니다.The runtime first searches the global assembly cache for the assembly that matches es-MX, but doesn't find it. 그런 다음, 런타임은 현재 실행 중인 어셈블리의 디렉터리에서 es-MX 디렉터리를 검색합니다.The runtime then searches the directory of the currently executing assembly for an es-MX directory. 이 시도에 실패하여 런타임은 다시 전역 어셈블리 캐시에서 적절한 대체 문화권을 반영하는 부모 어셈블리(이 경우 es(스페인어))를 검색합니다.Failing that, the runtime searches the global assembly cache again for a parent assembly that reflects the appropriate fallback culture — in this case, es (Spanish). 부모 어셈블리를 찾지 못하면 런타임은 해당 리소스를 찾을 때까지 부모 어셈블리의 모든 가능한 수준에서 es-MX 문화권을 검색합니다.If the parent assembly is not found, the runtime searches all potential levels of parent assemblies for the es-MX culture until it finds a corresponding resource. 리소스를 찾지 못하면 런타임은 기본 문화권의 리소스를 사용합니다.If a resource isn't found, the runtime uses the resource for the default culture.

.NET Framework 리소스 대체 프로세스 최적화Optimizing the .NET Framework Resource Fallback Process

다음과 같은 경우 런타임이 위성 어셈블리에서 리소스를 검색하는 프로세스를 최적화할 수 있습니다.Under the following conditions, you can optimize the process by which the runtime searches for resources in satellite assemblies

  • 위성 어셈블리는 코드 어셈블리와 동일한 위치에 배포됩니다.Satellite assemblies are deployed in the same location as the code assembly. 코드 어셈블리가 전역 어셈블리 캐시에 설치된 경우 위성 어셈블리도 전역 어셈블리 캐시에 설치됩니다.If the code assembly is installed in the Global Assembly Cache, satellite assemblies are also installed in the global assembly cache. 코드 어셈블리가 디렉터리에 설치된 경우 위성 어셈블리는 해당 디렉터리의 문화권별 폴더에 설치됩니다.If the code assembly is installed in a directory, satellite assemblies are installed in culture-specific folders of that directory.

  • 위성 어셈블리는 요청 시 설치되지 않습니다.Satellite assemblies are not installed on demand.

  • 애플리케이션 코드는 AppDomain.AssemblyResolve 이벤트를 처리하지 않습니다.Application code does not handle the AppDomain.AssemblyResolve event.

다음 예제와 같이 애플리케이션 구성 파일에 <relativeBindForResources> 요소를 포함하고 해당 enabled 특성을 true로 설정하여 위성 어셈블리에 대한 프로브를 최적화합니다.You optimize the probe for satellite assemblies by including the <relativeBindForResources> element and setting its enabled attribute to true in the application configuration file, as shown in the following example.

<configuration>
   <runtime>
      <relativeBindForResources enabled="true" />
   </runtime>
</configuration>

위성 어셈블리에 대해 최적화된 프로브는 옵트인 기능입니다.The optimized probe for satellite assemblies is an opt-in feature. 즉, 런타임은 <relativeBindForResources> 요소가 애플리케이션의 구성 파일에 있고 해당 enabled 특성이 true로 설정된 경우가 아니면 리소스 대체 프로세스에 문서화된 단계를 따릅니다.That is, the runtime follows the steps documented in The Resource Fallback Process unless the <relativeBindForResources> element is present in the application's configuration file and its enabled attribute is set to true. 이런 경우에는 위성 어셈블리 검색 프로세스가 다음과 같이 수정됩니다.If this is the case, the process of probing for a satellite assembly is modified as follows:

  • 런타임은 부모 코드 어셈블리의 위치를 사용하여 위성 어셈블리를 검색합니다.The runtime uses the location of the parent code assembly to probe for the satellite assembly. 부모 어셈블리가 전역 어셈블리 캐시에 설치된 경우 런타임은 캐시에서만 검색하고 애플리케이션 디렉터리에서 검색하지 않습니다.If the parent assembly is installed in the global assembly cache, the runtime probes in the cache but not in the application's directory. 부모 어셈블리가 애플리케이션 디렉터리에 설치된 경우 런타임은 애플리케이션 디렉터리에서만 검색하고 전역 어셈블리 캐시에서 검색하지 않습니다.If the parent assembly is installed in an application directory, the runtime probes in the application directory but not in the global assembly cache.

  • 런타임은 위성 어셈블리의 요청 시 설치에 대해 Windows Installer를 쿼리하지 않습니다.The runtime doesn't query the Windows Installer for on-demand installation of satellite assemblies.

  • 특정 리소스 어셈블리 검색이 실패할 경우 런타임에서 AppDomain.AssemblyResolve 이벤트가 발생하지 않습니다.If the probe for a particular resource assembly fails, the runtime does not raise the AppDomain.AssemblyResolve event.

.NET Core 리소스 대체 프로세스.NET Core resource fallback process

.NET Core 리소스 대체 프로세스에는 다음 단계가 포함됩니다.The .NET Core resource fallback process involves the following steps:

  1. 런타임에서 요청된 문화권에 대한 위성 어셈블리를 로드하려고 시도합니다.The runtime attempts to load a satellite assembly for the requested culture.

    • 현재 실행 중인 어셈블리의 디렉터리에서 요청된 문화권과 일치하는 하위 디렉터리를 확인합니다.Checks the directory of the currently executing assembly for a subdirectory that matches the requested culture. 하위 디렉터리를 찾으면 해당 하위 디렉터리에서 요청된 문화권에 유효한 위성 어셈블리를 검색하고 로드합니다.If it finds the subdirectory, it searches that subdirectory for a valid satellite assembly for the requested culture and loads it.

      참고

      대/소문자 구분 파일 시스템이 있는 운영 체제(즉, Linux 및 macOS)에서는 문화권 이름 하위 디렉터리 검색이 대/소문자를 구분합니다.On operating systems with case-sensitive file systems (that is, Linux and macOS), the culture name subdirectory search is case-sensitive. 하위 디렉터리 이름은 CultureInfo.Name(예: es 또는 es-MX)의 대/소문자와 정확히 일치해야 합니다.The subdirectory name must exactly match the case of the CultureInfo.Name (for example, es or es-MX).

      참고

      프로그래머가 AssemblyLoadContext에서 사용자 지정 어셈블리 로드 컨텍스트를 파생한 경우에는 상황이 복잡합니다.If the programmer has derived a custom assembly load context from AssemblyLoadContext, the situation is complicated. 실행 중인 어셈블리가 사용자 지정 컨텍스트에 로드된 경우 런타임에서 위성 어셈블리를 사용자 지정 컨텍스트에 로드합니다.If the executing assembly was loaded into the custom context, the runtime loads the satellite assembly into the custom context. 세부 정보는 이 문서의 범위를 벗어납니다.The details are out of scope for this document. AssemblyLoadContext을 참조하세요.See AssemblyLoadContext.

    • 위성 어셈블리를 찾지 못한 경우 AssemblyLoadContext에서 AssemblyLoadContext.Resolving 이벤트를 실행하여 위성 어셈블리를 찾을 수 없음을 표시합니다.If a satellite assemble has not been found, the AssemblyLoadContext raises the AssemblyLoadContext.Resolving event to indicate that it is unable to find the satellite assembly. 이벤트를 처리하도록 선택하면 이벤트 처리기가 위성 어셈블리에 대한 참조를 로드하고 반환할 수 있습니다.If you choose to handle the event, your event handler can load and return a reference to the satellite assembly.

    • 그래도 위성 어셈블리를 찾지 못하면 AssemblyLoadContext에서 AppDomain이 AppDomain.AssemblyResolve 이벤트를 트리거하여 위성 어셈블리를 찾을 수 없음을 표시하게 합니다.If a satellite assembly still has not been found, the AssemblyLoadContext causes the AppDomain to trigger an AppDomain.AssemblyResolve event to indicate that it is unable to find the satellite assembly. 이벤트를 처리하도록 선택하면 이벤트 처리기가 위성 어셈블리에 대한 참조를 로드하고 반환할 수 있습니다.If you choose to handle the event, your event handler can load and return a reference to the satellite assembly.

  2. 위성 어셈블리가 발견되면 런타임에서 요청된 리소스를 검색합니다.If a satellite assembly is found, the runtime searches it for the requested resource. 어셈블리에서 리소스를 찾으면 해당 리소스가 사용됩니다.If it finds the resource in the assembly, it uses it. 리소스를 찾지 못하면 검색을 계속합니다.If it doesn't find the resource, it continues the search.

    참고

    위성 어셈블리 내의 리소스를 찾기 위해 런타임은 ResourceManager에서 현재 CultureInfo.Name에 대해 요청한 리소스 파일을 검색합니다.To find a resource within the satellite assembly, the runtime searches for the resource file requested by the ResourceManager for the current CultureInfo.Name. 리소스 파일 내에서 요청된 리소스 이름을 검색합니다.Within the resource file it searches for the requested resource name. 둘 중 하나라도 찾지 못하면 리소스가 찾을 수 없는 것으로 처리됩니다.If either is not found, the resource is treated as not found.

  3. 런타임은 다음에 여러 잠재적인 수준에서 부모 문화권 어셈블리를 검색하며 매번 1-2단계를 반복합니다.The runtime next searches the parent culture assemblies through many potential levels, each time repeating steps 1 & 2.

    부모 문화권은 적절한 대체 문화권으로 정의됩니다.The parent culture is defined as an appropriate fallback culture. 리소스를 제공하는 것이 예외를 throw하는 것보다 낫기 때문에 부모를 대체 후보로 고려합니다.Consider parents as fallback candidates, because providing any resource is preferable to throwing an exception. 이 프로세스를 통해 리소스를 다시 사용할 수도 있습니다.This process also allows you to reuse resources. 자식 문화권이 요청된 리소스를 지역화할 필요가 없는 경우에만 부모 수준에 특정 리소스를 포함해야 합니다.You should include a particular resource at the parent level only if the child culture doesn't need to localize the requested resource. 예를 들어 en(중립 영어), en-GB(영국에서 사용되는 영어) 및 en-US(미국에서 사용되는 영어)에 대한 위성 어셈블리를 제공하는 경우 en 위성에 일반적인 용어가 포함되고, en-GBen-US 위성은 차이가 있는 용어에 대한 재정의만 제공합니다.For example, if you supply satellite assemblies for en (neutral English), en-GB (English as spoken in the United Kingdom), and en-US (English as spoken in the United States), the en satellite contains the common terminology, and the en-GB and en-US satellites provides overrides for only those terms that differ.

    각 문화권에는 CultureInfo.Parent 속성으로 정의된 부모 하나만 있지만 부모가 해당 부모를 포함할 수도 있습니다.Each culture has only one parent, which is defined by the CultureInfo.Parent property, but a parent might have its own parent. 문화권의 Parent 속성이 CultureInfo.InvariantCulture을 반환하면 부모 문화권 검색이 중지됩니다.The search for parent cultures stops when a culture's Parent property returns CultureInfo.InvariantCulture. 리소스 대체에서 고정 문화권은 부모 문화권 또는 리소스를 가질 수 있는 문화권으로 간주되지 않습니다.For resource fallback, the invariant culture is not considered a parent culture or a culture that can have resources.

  4. 원래 지정된 문화권 및 모든 부모를 검색했지만 리소스를 찾지 못하면 기본(대체) 문화권의 리소스가 사용됩니다.If the culture that was originally specified and all parents have been searched and the resource is still not found, the resource for the default (fallback) culture is used. 일반적으로 기본 문화권의 리소스는 주 애플리케이션 어셈블리에 포함되어 있습니다.Typically, the resources for the default culture are included in the main application assembly. 그러나 Location 속성에 대해 Satellite 값을 지정하여 리소스의 최종 대체 위치가 주 어셈블리가 아니라 위성 어셈블리임을 나타낼 수 있습니다.However, you can specify a value of Satellite for the Location property to indicate that the ultimate fallback location for resources is a satellite assembly rather than the main assembly.

    참고

    기본 리소스는 주 어셈블리와 함께 컴파일할 수 있는 유일한 리소스입니다.The default resource is the only resource that can be compiled with the main assembly. NeutralResourcesLanguageAttribute 특성을 사용하여 위성 어셈블리를 지정하지 않을 경우 이 리소스가 최종 대체(최종 부모)입니다.Unless you specify a satellite assembly by using the NeutralResourcesLanguageAttribute attribute, it is the ultimate fallback (final parent). 따라서 주 어셈블리에 기본 리소스 집합을 항상 포함하는 것이 좋습니다.Therefore, we recommend that you always include a default set of resources in your main assembly. 이렇게 하면 예외가 throw되지 않도록 방지하는 데 도움이 됩니다.This helps prevent exceptions from being thrown. 기본 리소스 파일을 포함하여 모든 리소스에 대한 대체를 제공하고 문화권별 리소스는 아니라도 사용자에게 항상 리소스가 하나 이상 제공되도록 합니다.By including a default resource file, you provide a fallback for all resources and ensure that at least one resource is always present for the user, even if it is not culturally specific.

  5. 마지막으로, 런타임이 기본(대체) 문화권의 리소스 파일을 찾지 못하면 MissingManifestResourceException 또는 MissingSatelliteAssemblyException 예외가 throw되어 리소스를 찾을 수 없음을 나타냅니다.Finally, if the runtime doesn't find a resource file for a default (fallback) culture, a MissingManifestResourceException or MissingSatelliteAssemblyException exception is thrown to indicate that the resource could not be found. 리소스 파일이 있지만 요청된 리소스가 없는 경우 요청에서 null을 반환합니다.If the resource file is found but the requested resource is not present the request returns null.

위성 어셈블리에 대한 최종 대체Ultimate Fallback to Satellite Assembly

필요에 따라 주 어셈블리에서 리소스를 제거하고 런타임이 특정 문화권에 해당하는 위성 어셈블리에서 최종 대체 리소스를 로드하도록 지정할 수 있습니다.You can optionally remove resources from the main assembly and specify that the runtime should load the ultimate fallback resources from a satellite assembly that corresponds to a specific culture. 대체 프로세스를 제어하려면 NeutralResourcesLanguageAttribute(String, UltimateResourceFallbackLocation) 생성자를 사용하고 리소스 관리자가 주 어셈블리 또는 위성 어셈블리에서 대체 리소스를 추출해야 하는지를 지정하는 UltimateResourceFallbackLocation 매개 변수의 값을 제공합니다.To control the fallback process, you use the NeutralResourcesLanguageAttribute(String, UltimateResourceFallbackLocation) constructor and supply a value for the UltimateResourceFallbackLocation parameter that specifies whether Resource Manager should extract the fallback resources from the main assembly or from a satellite assembly.

다음 .NET Framework 예제에서는 NeutralResourcesLanguageAttribute 특성을 사용하여 프랑스어(fr)에 대한 위성 어셈블리에 애플리케이션의 대체 리소스를 저장합니다.The following .NET Framework example uses the NeutralResourcesLanguageAttribute attribute to store an application's fallback resources in a satellite assembly for the French (fr) language. 이 예제에는 Greeting이라는 단일 문자열 리소스를 정의하는 두 개의 텍스트 기반 리소스 파일이 있습니다.The example has two text-based resource files that define a single string resource named Greeting. 첫 번째 resources.fr.txt에는 프랑스어 리소스가 들어 있습니다.The first, resources.fr.txt, contains a French language resource.

Greeting=Bon jour!

두 번째 resources,ru.txt에는 러시아어 리소스가 들어 있습니다.The second, resources,ru.txt, contains a Russian language resource.

Greeting=Добрый день

명령줄에서 리소스 파일 생성기(Resgen.exe)를 실행하여 이러한 두 파일을 .resources 파일로 컴파일합니다.These two files are compiled to .resources files by running the resource file generator (Resgen.exe) from the command line. 프랑스어 리소스에 대한 명령은 다음과 같습니다.For the French language resource, the command is:

resgen.exe resources.fr.txtresgen.exe resources.fr.txt

러시아어 리소스에 대한 명령은 다음과 같습니다.For the Russian language resource, the command is:

resgen.exe resources.ru.txtresgen.exe resources.ru.txt

프랑스어 리소스에 대한 명령줄에서 다음과 같이 어셈블리 링커(Al.exe) 명령을 실행하여 .resources 파일을 동적 연결 라이브러리에 포함합니다.The .resources files are embedded into dynamic link libraries by running assembly linker (Al.exe) from the command line for the French language resource as follows:

al /t:lib /embed:resources.fr.resources /culture:fr /out:fr\Example1.resources.dllal /t:lib /embed:resources.fr.resources /culture:fr /out:fr\Example1.resources.dll

러시아어 리소스의 경우 다음과 같이 명령을 실행합니다.and for the Russian language resource as follows:

al /t:lib /embed:resources.ru.resources /culture:ru /out:ru\Example1.resources.dllal /t:lib /embed:resources.ru.resources /culture:ru /out:ru\Example1.resources.dll

애플리케이션 소스 코드는 Example1.cs 또는 Example1.vb라는 파일에 있습니다.The application source code resides in a file named Example1.cs or Example1.vb. NeutralResourcesLanguageAttribute 특성을 포함하여 기본 애플리케이션 리소스가 fr 하위 디렉터리에 있음을 나타냅니다.It includes the NeutralResourcesLanguageAttribute attribute to indicate that the default application resource is in the fr subdirectory. 리소스 관리자를 인스턴스화하고, Greeting 리소스의 값을 검색하여 콘솔에 표시합니다.It instantiates the Resource Manager, retrieves the value of the Greeting resource, and displays it to the console.

using System;
using System.Reflection;
using System.Resources;

[assembly:NeutralResourcesLanguage("fr", UltimateResourceFallbackLocation.Satellite)]

public class Example
{
   public static void Main()
   {
      ResourceManager rm = new ResourceManager("resources",
                                               typeof(Example).Assembly);
      string greeting = rm.GetString("Greeting");
      Console.WriteLine(greeting);
   }
}
Imports System.Reflection
Imports System.Resources

<Assembly:NeutralResourcesLanguage("fr", UltimateResourceFallbackLocation.Satellite)>
Module Example
   Public Sub Main()
      Dim rm As New ResourceManager("resources", GetType(Example).Assembly)
      Dim greeting As String = rm.GetString("Greeting")
      Console.WriteLine(greeting) 
   End Sub
End Module

명령줄에서 다음과 같이 C# 소스 코드를 컴파일할 수 있습니다.You can then compile C# source code from the command line as follows:

csc Example1.cs

Visual Basic 컴파일러에 대한 명령도 다음과 같이 매우 유사합니다.The command for the Visual Basic compiler is very similar:

vbc Example1.vb

주 어셈블리에 포함된 리소스가 없기 때문에 /resource 스위치를 사용하여 컴파일할 필요가 없습니다.Because there are no resources embedded in the main assembly, you do not have to compile by using the /resource switch.

러시아어 이외의 언어를 사용하는 시스템에서 예제를 실행할 경우 다음과 같은 출력이 표시됩니다.When you run the example from a system whose language is anything other than Russian, it displays the following output:

Bon jour!

패키징 대체 방법 제안Suggested Packaging Alternative

시간 또는 예산 제약 조건으로 인해 애플리케이션이 지원하는 모든 하위 문화권의 리소스 집합을 만들지 못할 수도 있습니다.Time or budget constraints might prevent you from creating a set of resources for every subculture that your application supports. 대신, 부모 문화권에 대해 관련된 모든 하위 문화권이 사용할 수 있는 단일 위성 어셈블리를 만들 수 있습니다.Instead, you can create a single satellite assembly for a parent culture that all related subcultures can use. 예를 들어 지역별 영어 리소스를 요청하는 사용자가 검색하는 단일 영어 위성 어셈블리(en) 및 지역별 독일어 리소스를 요청하는 사용자를 위한 단일 독일어 위성 어셈블리(de)를 제공할 수 있습니다.For example, you can provide a single English satellite assembly (en) that is retrieved by users who request region-specific English resources, and a single German satellite assembly (de) for users who request region-specific German resources. 예를 들어 독일에서 사용되는 독일어(de-DE), 오스트리아에서 사용되는 독일어(de-AT), 스위스에서 사용되는 독일어(de-CH) 요청은 독일어 위성 어셈블리(de)로 대체됩니다.For example, requests for German as spoken in Germany (de-DE), Austria (de-AT), and Switzerland (de-CH) would fall back to the German satellite assembly (de). 기본 리소스는 최종 대체라서 대부분의 애플리케이션 사용자가 요청하는 리소스여야 하므로 이러한 리소스를 선택할 때는 주의하세요.The default resources are the final fallback and therefore should be the resources that will be requested by the majority of your application's users, so choose these resources carefully. 이 접근 방법은 문화권별 성격이 약한 리소스를 배포하지만 애플리케이션의 지역화 비용을 훨씬 줄일 수 있습니다.This approach deploys resources that are less culturally specific, but can significantly reduce your application's localization costs.

참조See also