Mengemas dan menyebarkan sumber daya di aplikasi .NET

Aplikasi mengandalkan .NET Framework Resource Manager, yang ResourceManager diwakili oleh kelas , untuk mengambil sumber daya yang dilokalkan. Resource Manager mengasumsikan bahwa model hub dan spoke digunakan untuk mengemas dan menyebarkan sumber daya. Hub adalah rakitan utama yang berisi kode yang dapat dieksekusi yang tidak dapat diskalakan dan sumber daya untuk satu budaya, yang disebut budaya netral atau default. Budaya default adalah budaya fallback untuk aplikasi; ini adalah budaya yang sumber dayanya digunakan jika sumber daya yang dilokalkan tidak dapat ditemukan. Setiap spoke terhubung ke rakitan satelit yang berisi sumber daya untuk satu budaya, tetapi tidak berisi kode apa pun.

Ada beberapa keuntungan dari model ini:

  • Anda dapat secara bertahap menambahkan sumber daya untuk budaya baru setelah Anda menyebarkan aplikasi. Karena pengembangan sumber daya khusus budaya berikutnya dapat membutuhkan waktu yang signifikan, ini memungkinkan Anda untuk merilis aplikasi utama Anda terlebih dahulu, dan memberikan sumber daya khusus budaya di kemudian hari.
  • Anda dapat memperbarui dan mengubah rakitan satelit aplikasi tanpa mengolah ulang aplikasi.
  • Aplikasi hanya perlu memuat rakitan satelit yang berisi sumber daya yang diperlukan untuk budaya tertentu. Ini dapat secara signifikan mengurangi penggunaan sumber daya sistem.

Namun, ada juga kerugian untuk model ini:

  • Anda harus mengelola beberapa set sumber daya.
  • Biaya awal pengujian aplikasi meningkat, karena Anda harus menguji beberapa konfigurasi. Perhatikan bahwa dalam jangka panjang akan lebih mudah dan lebih murah untuk menguji satu aplikasi inti dengan beberapa satelit, daripada menguji dan memelihara beberapa versi internasional paralel.

Konvensi penamaan sumber daya

Saat mengemas sumber daya aplikasi, Anda harus menamainya menggunakan konvensi penamaan sumber daya yang diharapkan runtime bahasa umum. Runtime mengidentifikasi sumber daya dengan nama budayanya. Setiap budaya diberi nama yang unik, yang biasanya merupakan kombinasi dari nama budaya huruf kecil dua huruf yang terkait dengan bahasa dan, jika diperlukan, nama subkultur dua huruf besar yang terkait dengan negara atau wilayah. Nama subkultur mengikuti nama budaya, dipisahkan oleh tanda hubung (-). Contohnya termasuk ja-JP untuk bahasa Jepang seperti yang diucapkan di Jepang, en-US untuk bahasa Inggris seperti yang diucapkan dalam Amerika Serikat, de-DE untuk bahasa Jerman seperti yang diucapkan di Jerman, atau de-AT untuk bahasa Jerman seperti yang diucapkan di Austria. Lihat kolom Tag bahasa dalam daftar nama bahasa/wilayah yang didukung oleh Windows. Nama budaya mengikuti standar yang ditentukan oleh BCP 47.

Catatan

Ada beberapa pengecualian untuk nama budaya dua huruf, seperti zh-Hans untuk Bahasa Tionghoa (Disederhanakan).

Untuk informasi selengkapnya, lihat Membuat file sumber daya dan Membuat rakitan satelit.

Proses fallback sumber daya

Model hub dan spoke untuk pengemasan dan penyebaran sumber daya menggunakan proses fallback untuk menemukan sumber daya yang sesuai. Jika aplikasi meminta sumber daya yang dilokalkan yang tidak tersedia, runtime bahasa umum mencari hierarki budaya untuk sumber daya fallback yang sesuai yang paling cocok dengan permintaan aplikasi pengguna, dan melemparkan pengecualian hanya sebagai upaya terakhir. Pada setiap tingkat hierarki, jika sumber daya yang sesuai ditemukan, runtime menggunakannya. Jika sumber daya tidak ditemukan, pencarian berlanjut di tingkat berikutnya.

Untuk meningkatkan performa pencarian, terapkan NeutralResourcesLanguageAttribute atribut ke assembly utama Anda, dan berikan nama bahasa netral yang akan berfungsi dengan assembly utama Anda.

Proses fallback sumber daya .NET Framework

Proses fallback sumber daya .NET Framework melibatkan langkah-langkah berikut:

Tip

Anda mungkin dapat menggunakan <elemen konfigurasi relativeBindForResources> untuk mengoptimalkan proses fallback sumber daya dan proses di mana runtime pemeriksaan untuk rakitan sumber daya. Untuk informasi selengkapnya, lihat Mengoptimalkan proses fallback sumber daya.

  1. Runtime pertama memeriksa cache perakitan global untuk assembly yang cocok dengan budaya yang diminta untuk aplikasi Anda.

    Cache rakitan global dapat menyimpan rakitan sumber daya yang dibagikan oleh banyak aplikasi. Ini membebaskan Anda dari harus menyertakan set sumber daya tertentu dalam struktur direktori setiap aplikasi yang Anda buat. Jika runtime menemukan referensi ke assembly, runtime akan mencari assembly untuk sumber daya yang diminta. Jika menemukan entri di rakitan, entri menggunakan sumber daya yang diminta. Jika tidak menemukan entri, entri akan melanjutkan pencarian.

  2. Runtime berikutnya memeriksa direktori rakitan yang saat ini dijalankan untuk subdirektori yang cocok dengan budaya yang diminta. Jika menemukan subdirektori, subdirektori tersebut mencari perakitan satelit yang valid untuk budaya yang diminta. Runtime kemudian mencari perakitan satelit untuk sumber daya yang diminta. Jika menemukan sumber daya di rakitan, sumber daya akan menggunakannya. Jika tidak menemukan sumber daya, sumber daya akan melanjutkan pencarian.

  3. Runtime berikutnya meminta Penginstal Windows untuk menentukan apakah rakitan satelit akan diinstal sesuai permintaan. Jika demikian, ia menangani penginstalan, memuat perakitan, dan mencarinya atau sumber daya yang diminta. Jika menemukan sumber daya di rakitan, sumber daya akan menggunakannya. Jika tidak menemukan sumber daya, sumber daya akan melanjutkan pencarian.

  4. Runtime meningkatkan AppDomain.AssemblyResolve peristiwa untuk menunjukkan bahwa tidak dapat menemukan rakitan satelit. Jika Anda memilih untuk menangani peristiwa, penanganan aktivitas Anda dapat mengembalikan referensi ke rakitan satelit yang sumber dayanya akan digunakan untuk pencarian. Jika tidak, penanganan aktivitas akan kembali null dan pencarian berlanjut.

  5. Runtime berikutnya mencari cache assembly global lagi, kali ini untuk rakitan induk dari budaya yang diminta. Jika rakitan induk ada di cache perakitan global, runtime mencari perakitan untuk sumber daya yang diminta.

    Budaya induk didefinisikan sebagai budaya fallback yang sesuai. Anggap orang tua sebagai kandidat fallback, karena menyediakan sumber daya apa pun lebih disukai untuk memberikan pengecualian. Proses ini juga memungkinkan Anda untuk menggunakan kembali sumber daya. Anda harus menyertakan sumber daya tertentu di tingkat induk hanya jika budaya anak tidak perlu melokalisasi sumber daya yang diminta. Misalnya, jika Anda menyediakan rakitan satelit untuk en (bahasa Inggris netral), en-GB (bahasa Inggris seperti yang diucapkan di Inggris), dan en-US (bahasa Inggris seperti yang diucapkan dalam Amerika Serikat), en satelit akan berisi terminologi umum, dan en-GB satelit dan en-US dapat memberikan pengambiran hanya untuk istilah-istilah yang berbeda.

  6. Runtime berikutnya memeriksa direktori rakitan yang sedang dijalankan untuk melihat apakah berisi direktori induk. Jika direktori induk ada, runtime mencari direktori untuk rakitan satelit yang valid untuk budaya induk. Jika menemukan assembly, runtime mencari assembly untuk sumber daya yang diminta. Jika menemukan sumber daya, sumber daya akan menggunakannya. Jika tidak menemukan sumber daya, sumber daya akan melanjutkan pencarian.

  7. Runtime berikutnya meminta Penginstal Windows untuk menentukan apakah rakitan satelit induk akan diinstal sesuai permintaan. Jika demikian, ia menangani penginstalan, memuat perakitan, dan mencarinya atau sumber daya yang diminta. Jika menemukan sumber daya di rakitan, sumber daya akan menggunakannya. Jika tidak menemukan sumber daya, sumber daya akan melanjutkan pencarian.

  8. Runtime meningkatkan AppDomain.AssemblyResolve peristiwa untuk menunjukkan bahwa tidak dapat menemukan sumber daya fallback yang sesuai. Jika Anda memilih untuk menangani peristiwa, penanganan aktivitas Anda dapat mengembalikan referensi ke rakitan satelit yang sumber dayanya akan digunakan untuk pencarian. Jika tidak, penanganan aktivitas akan kembali null dan pencarian berlanjut.

  9. Runtime berikutnya mencari rakitan induk, seperti pada tiga langkah sebelumnya, melalui banyak tingkat potensial. Setiap budaya hanya memiliki satu induk, yang didefinisikan oleh CultureInfo.Parent properti , tetapi induk mungkin memiliki induknya sendiri. Pencarian budaya induk berhenti ketika properti budaya Parent kembali CultureInfo.InvariantCulture; untuk fallback sumber daya, budaya invarian tidak dianggap sebagai budaya induk atau budaya yang dapat memiliki sumber daya.

  10. Jika budaya yang awalnya ditentukan dan semua orang tua telah dicari dan sumber daya masih belum ditemukan, sumber daya untuk budaya default (fallback) digunakan. Biasanya, sumber daya untuk budaya default disertakan dalam perakitan aplikasi utama. Namun, Anda dapat menentukan nilai Satellite untuk Location properti NeutralResourcesLanguageAttribute atribut untuk menunjukkan bahwa lokasi fallback utama untuk sumber daya adalah rakitan satelit, bukan perakitan utama.

    Catatan

    Sumber daya default adalah satu-satunya sumber daya yang dapat dikompilasi dengan rakitan utama. Kecuali Anda menentukan rakitan satelit dengan menggunakan NeutralResourcesLanguageAttribute atribut , itu adalah fallback utama (induk akhir). Oleh karena itu, kami sarankan Anda selalu menyertakan sekumpulan sumber daya default di perakitan utama Anda. Ini membantu mencegah pengecualian dilemparkan. Dengan menyertakan sumber daya default, file yang Anda berikan fallback untuk semua sumber daya dan memastikan bahwa setidaknya satu sumber daya selalu ada untuk pengguna, meskipun tidak spesifik secara budaya.

  11. Terakhir, jika runtime tidak menemukan sumber daya untuk budaya MissingManifestResourceException default (fallback), atau MissingSatelliteAssemblyException pengecualian dilemparkan untuk menunjukkan bahwa sumber daya tidak dapat ditemukan.

Misalnya, aplikasi meminta sumber daya yang dilokalkan untuk Spanyol (Meksiko) ( es-MX budaya). Runtime pertama mencari cache rakitan global untuk rakitan yang cocok es-MX, tetapi tidak menemukannya. Runtime kemudian mencari direktori assembly yang sedang dijalankan untuk es-MX direktori. Gagal itu, runtime mencari cache perakitan global lagi untuk assembly induk yang mencerminkan budaya fallback yang sesuai — dalam hal ini, es (Spanyol). Jika rakitan induk tidak ditemukan, runtime mencari semua tingkat potensi rakitan induk untuk es-MX budaya sampai menemukan sumber daya yang sesuai. Jika sumber daya tidak ditemukan, runtime menggunakan sumber daya untuk budaya default.

Mengoptimalkan proses fallback sumber daya .NET Framework

Dalam kondisi berikut, Anda dapat mengoptimalkan proses di mana runtime mencari sumber daya di rakitan satelit:

  • Rakitan satelit disebarkan di lokasi yang sama dengan rakitan kode. Jika rakitan kode diinstal di Global Assembly Cache, rakitan satelit juga diinstal di cache perakitan global. Jika rakitan kode diinstal di direktori, rakitan satelit dipasang di folder khusus budaya direktori tersebut.

  • Rakitan satelit tidak diinstal sesuai permintaan.

  • Kode aplikasi tidak menangani AppDomain.AssemblyResolve peristiwa.

Anda mengoptimalkan pemeriksaan untuk rakitan satelit dengan menyertakan <elemen relativeBindForResources> dan mengatur atributnya enabled ke true dalam file konfigurasi aplikasi, seperti yang ditunjukkan dalam contoh berikut.

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

Pemeriksaan yang dioptimalkan untuk rakitan satelit adalah fitur keikutsertaan. Artinya, runtime mengikuti langkah-langkah yang didokumenkan dalam Proses fallback sumber daya kecuali <elemen relativeBindForResources> ada dalam file konfigurasi aplikasi dan atributnya enabled diatur ke true. Jika demikian, proses pemeriksaan untuk rakitan satelit dimodifikasi sebagai berikut:

  • Runtime menggunakan lokasi perakitan kode induk untuk menyelidiki perakitan satelit. Jika rakitan induk diinstal di cache perakitan global, runtime pemeriksaan di cache tetapi tidak di direktori aplikasi. Jika rakitan induk diinstal dalam direktori aplikasi, runtime pemeriksaan di direktori aplikasi tetapi tidak di cache perakitan global.

  • Runtime tidak mengkueri Penginstal Windows untuk penginstalan rakitan satelit sesuai permintaan.

  • Jika pemeriksaan untuk rakitan sumber daya tertentu gagal, runtime tidak menaikkan AppDomain.AssemblyResolve peristiwa.

Proses fallback sumber daya .NET Core

Proses fallback sumber daya .NET Core melibatkan langkah-langkah berikut:

  1. Runtime mencoba memuat rakitan satelit untuk budaya yang diminta.

    • Memeriksa direktori rakitan yang sedang dijalankan untuk subdirektori yang cocok dengan budaya yang diminta. Jika menemukan subdirektori, subdirektori tersebut mencari perakitan satelit yang valid untuk budaya yang diminta dan memuatnya.

      Catatan

      Pada sistem operasi dengan sistem file peka huruf besar/kecil (yaitu, Linux dan macOS), pencarian subdirektori nama budaya peka huruf besar/kecil. Nama subdirektori harus sama persis dengan huruf besar/kecil CultureInfo.Name (misalnya, es atau es-MX).

      Catatan

      Jika programmer telah memperoleh konteks beban rakitan kustom dari AssemblyLoadContext, situasinya rumit. Jika rakitan yang dijalankan dimuat ke dalam konteks kustom, runtime memuat rakitan satelit ke dalam konteks kustom. Detailnya di luar cakupan untuk dokumen ini. Lihat AssemblyLoadContext.

    • Jika satelit merakit belum ditemukan, AssemblyLoadContext muncul AssemblyLoadContext.Resolving peristiwa untuk menunjukkan bahwa ia tidak dapat menemukan rakitan satelit. Jika Anda memilih untuk menangani peristiwa, penanganan aktivitas Anda dapat memuat dan mengembalikan referensi ke perakitan satelit.

    • Jika rakitan satelit masih belum ditemukan, AssemblyLoadContext menyebabkan AppDomain memicu AppDomain.AssemblyResolve peristiwa untuk menunjukkan bahwa tidak dapat menemukan rakitan satelit. Jika Anda memilih untuk menangani peristiwa, penanganan aktivitas Anda dapat memuat dan mengembalikan referensi ke perakitan satelit.

  2. Jika rakitan satelit ditemukan, runtime mencarinya untuk sumber daya yang diminta. Jika menemukan sumber daya di rakitan, sumber daya akan menggunakannya. Jika tidak menemukan sumber daya, sumber daya akan melanjutkan pencarian.

    Catatan

    Untuk menemukan sumber daya dalam rakitan satelit, runtime mencari file sumber daya yang ResourceManager diminta oleh untuk saat ini CultureInfo.Name. Dalam file sumber daya, ia mencari nama sumber daya yang diminta. Jika keduanya tidak ditemukan, sumber daya diperlakukan sebagai tidak ditemukan.

  3. Runtime berikutnya mencari rakitan budaya induk melalui banyak tingkat potensial, setiap kali mengulangi langkah 1 & 2.

    Budaya induk didefinisikan sebagai budaya fallback yang sesuai. Anggap orang tua sebagai kandidat fallback, karena menyediakan sumber daya apa pun lebih disukai untuk memberikan pengecualian. Proses ini juga memungkinkan Anda untuk menggunakan kembali sumber daya. Anda harus menyertakan sumber daya tertentu di tingkat induk hanya jika budaya anak tidak perlu melokalisasi sumber daya yang diminta. Misalnya, jika Anda menyediakan rakitan satelit untuk en (bahasa Inggris netral), en-GB (bahasa Inggris seperti yang diucapkan di Inggris), dan en-US (bahasa Inggris seperti yang diucapkan dalam Amerika Serikat), en satelit berisi terminologi umum, dan en-GB satelit dan en-US memberikan penimpaan hanya untuk istilah-istilah yang berbeda.

    Setiap budaya hanya memiliki satu induk, yang didefinisikan oleh CultureInfo.Parent properti , tetapi induk mungkin memiliki induknya sendiri. Pencarian budaya induk berhenti ketika properti budaya Parent kembali CultureInfo.InvariantCulture. Untuk fallback sumber daya, budaya invarian tidak dianggap sebagai budaya induk atau budaya yang dapat memiliki sumber daya.

  4. Jika budaya yang awalnya ditentukan dan semua orang tua telah dicari dan sumber daya masih belum ditemukan, sumber daya untuk budaya default (fallback) digunakan. Biasanya, sumber daya untuk budaya default disertakan dalam perakitan aplikasi utama. Namun, Anda dapat menentukan nilai Satellite untuk Location properti untuk menunjukkan bahwa lokasi fallback utama untuk sumber daya adalah rakitan satelit daripada perakitan utama.

    Catatan

    Sumber daya default adalah satu-satunya sumber daya yang dapat dikompilasi dengan rakitan utama. Kecuali Anda menentukan rakitan satelit dengan menggunakan NeutralResourcesLanguageAttribute atribut , itu adalah fallback utama (induk akhir). Oleh karena itu, kami sarankan Anda selalu menyertakan sekumpulan sumber daya default di perakitan utama Anda. Ini membantu mencegah pengecualian dilemparkan. Dengan menyertakan file sumber daya default, Anda menyediakan fallback untuk semua sumber daya dan memastikan bahwa setidaknya satu sumber daya selalu ada untuk pengguna, meskipun tidak spesifik secara budaya.

  5. Terakhir, jika runtime tidak menemukan file sumber daya untuk budaya default (fallback), MissingManifestResourceException atau MissingSatelliteAssemblyException pengecualian dilemparkan untuk menunjukkan bahwa sumber daya tidak dapat ditemukan. Jika file sumber daya ditemukan tetapi sumber daya yang diminta tidak ada permintaan mengembalikan null.

Fallback utama ke rakitan satelit

Anda dapat secara opsional menghapus sumber daya dari rakitan utama dan menentukan bahwa runtime harus memuat sumber daya fallback utama dari rakitan satelit yang sesuai dengan budaya tertentu. Untuk mengontrol proses fallback, Anda menggunakan NeutralResourcesLanguageAttribute(String, UltimateResourceFallbackLocation) konstruktor dan menyediakan nilai untuk UltimateResourceFallbackLocation parameter yang menentukan apakah Resource Manager harus mengekstrak sumber daya fallback dari rakitan utama atau dari rakitan satelit.

Contoh .NET Framework berikut menggunakan NeutralResourcesLanguageAttribute atribut untuk menyimpan sumber daya fallback aplikasi dalam rakitan satelit untuk bahasa Prancis (fr). Contohnya memiliki dua file sumber daya berbasis teks yang menentukan satu sumber daya string bernama Greeting. Yang pertama, resources.fr.txt, berisi sumber daya bahasa Prancis.

Greeting=Bon jour!

Sumber daya kedua, ru.txt, berisi sumber daya bahasa Rusia.

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

Kedua file ini dikompilasi ke file .resources dengan menjalankan Resource File Generator (resgen.exe) dari baris perintah. Untuk sumber daya bahasa Prancis, perintahnya adalah:

resgen.exe resources.fr.txt

Untuk sumber daya bahasa Rusia, perintahnya adalah:

resgen.exe resources.ru.txt

File .resources disematkan ke dalam pustaka tautan dinamis dengan menjalankan Assembly Linker (al.exe) dari baris perintah untuk sumber daya bahasa Prancis sebagai berikut:

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

dan untuk sumber daya bahasa Rusia sebagai berikut:

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

Kode sumber aplikasi berada dalam file bernama Example1.cs atau Example1.vb. Ini termasuk NeutralResourcesLanguageAttribute atribut untuk menunjukkan bahwa sumber daya aplikasi default berada di subdirektori fr. Ini membuat instans Resource Manager, mengambil nilai Greeting sumber daya, dan menampilkannya ke konsol.

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

Anda kemudian dapat mengkompilasi kode sumber C# dari baris perintah sebagai berikut:

csc Example1.cs

Perintah untuk pengkompilasi Visual Basic sangat mirip:

vbc Example1.vb

Karena tidak ada sumber daya yang disematkan di rakitan utama, Anda tidak perlu mengkompilasi dengan menggunakan sakelar /resource .

Saat Anda menjalankan contoh dari sistem yang bahasanya apa pun selain Bahasa Rusia, contoh tersebut akan menampilkan output berikut:

Bon jour!

Alternatif pengemasan yang disarankan

Batasan waktu atau anggaran dapat mencegah Anda membuat sekumpulan sumber daya untuk setiap subkultur yang didukung aplikasi Anda. Sebagai gantinya, Anda dapat membuat satu rakitan satelit untuk budaya induk yang dapat digunakan semua subkultur terkait. Misalnya, Anda dapat menyediakan satu rakitan satelit Bahasa Inggris (en) yang diambil oleh pengguna yang meminta sumber daya bahasa Inggris khusus wilayah, dan satu perakitan satelit Jerman (de) untuk pengguna yang meminta sumber daya Jerman khusus wilayah. Misalnya, permintaan untuk bahasa Jerman seperti yang diucapkan di Jerman (de-DE), Austria (de-AT), dan Swiss (de-CH) akan kembali ke perakitan satelit Jerman (de). Sumber daya default adalah fallback akhir dan oleh karena itu harus menjadi sumber daya yang akan diminta oleh sebagian besar pengguna aplikasi Anda, jadi pilih sumber daya ini dengan hati-hati. Pendekatan ini menyebarkan sumber daya yang kurang spesifik secara budaya, tetapi dapat secara signifikan mengurangi biaya pelokalan aplikasi Anda.

Lihat juga