Anwar Minarso

See also: Other Geeks@INDC

Multilingual ResourceManager dgn Auto Translate (Part I)

Dalam pengembangan aplikasi, multi language merupakan point plus dalam aplikasi. Dalam .NET sendiri fitur tersebut sudah ada yaitu menggunakan ResourceManager, namun dalam prakteknya setiap bahasa kita membutuhkan tenaga kerja yg menguasai bahasa terkait, dan juga harus mencompile dan mendeploy kembali. Tentunya ujung2nya adalah waktu dan cost.

Source code dapat didownload di sini

Dalam postingan kali ini saya akan memberikan contoh membuat Custom ResourceManager dgn implementasi service Translator Microsoft. Contoh screennya adalah sbb :

English

Indonesian

Japanese

Korean

Cukup menarik bukan ?

Sebelum menyentuh lebih dalam, sebaiknya lihat dahulu link dibawah ini :

  1. ResourceManager, detail penggunanaannya dapat dilihat pada http://msdn.microsoft.com/en-us/library/aa905797.aspx.
  2. Contoh Implementasi Translator telah posting oleh teman kita Yugie, linknya adalah http://students.netindonesia.net/blogs/yugie/archive/2011/03/02/mudah-translator-dengan-bing-web-service.aspx
  3. Dan juga untuk detail API Translator dapat dilihat pada http://api.microsofttranslator.com/

Jika sudah membaca link diatas, oke kita lanjut....

Saya membuat enum LanguageType dan Extensionnya, tujuannya untuk mapping dengan API Translator dan juga mapping CultureInfonya

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Globalization;
  6. namespace MyResourceManager
  7. {
  8.     public enum LanguageType
  9.     {
  10.         AutoDetect,
  11.         Arabic,
  12.         Bulgarian,
  13.         Catalan,
  14.         Chinese_Simplified,
  15.         Chinese_Traditional,
  16.         Czech,
  17.         Danish,
  18.         Dutch,
  19.         English,
  20.         Estonian,
  21.         Finnish,
  22.         French,
  23.         German,
  24.         Greek,
  25.         Haitian_Creole,
  26.         Hebrew,
  27.         Hungarian,
  28.         Indonesian,
  29.         Italian,
  30.         Japanese,
  31.         Korean,
  32.         Latvian,
  33.         Lithuanian,
  34.         Norwegian,
  35.         Polish,
  36.         Portuguese,
  37.         Romanian,
  38.         Russian,
  39.         Slovak,
  40.         Slovenian,
  41.         Spanish,
  42.         Swedish,
  43.         Thai,
  44.         Turkish,
  45.         Ukrainian,
  46.         Vietnamese
  47.     }
  48.     public static class LanguageTypeExtension
  49.     {
  50.         public static string GetLanguageCode(this LanguageType value)
  51.         {
  52.             switch (value)
  53.             {
  54.                 case LanguageType.AutoDetect:
  55.                     return "";
  56.                 case LanguageType.Arabic:
  57.                     return "ar";
  58.                 case LanguageType.Bulgarian:
  59.                     return "bg";
  60.                 case LanguageType.Catalan:
  61.                     return "ca";
  62.                 case LanguageType.Chinese_Simplified:
  63.                     return "zh-CHS";
  64.                 case LanguageType.Chinese_Traditional:
  65.                     return "zh-CHT";
  66.                 case LanguageType.Czech:
  67.                     return "cs";
  68.                 case LanguageType.Danish:
  69.                     return "da";
  70.                 case LanguageType.Dutch:
  71.                     return "nl";
  72.                 case LanguageType.English:
  73.                     return "en";
  74.                 case LanguageType.Estonian:
  75.                     return "et";
  76.                 case LanguageType.Finnish:
  77.                     return "fi";
  78.                 case LanguageType.French:
  79.                     return "fr";
  80.                 case LanguageType.German:
  81.                     return "de";
  82.                 case LanguageType.Greek:
  83.                     return "el";
  84.                 case LanguageType.Haitian_Creole:
  85.                     return "ht";
  86.                 case LanguageType.Hebrew:
  87.                     return "he";
  88.                 case LanguageType.Hungarian:
  89.                     return "hu";
  90.                 case LanguageType.Indonesian:
  91.                     return "id";
  92.                 case LanguageType.Italian:
  93.                     return "it";
  94.                 case LanguageType.Japanese:
  95.                     return "ja";
  96.                 case LanguageType.Korean:
  97.                     return "ko";
  98.                 case LanguageType.Latvian:
  99.                     return "lv";
  100.                 case LanguageType.Lithuanian:
  101.                     return "lt";
  102.                 case LanguageType.Norwegian:
  103.                     return "no";
  104.                 case LanguageType.Polish:
  105.                     return "pl";
  106.                 case LanguageType.Portuguese:
  107.                     return "pt";
  108.                 case LanguageType.Romanian:
  109.                     return "ro";
  110.                 case LanguageType.Russian:
  111.                     return "ru";
  112.                 case LanguageType.Slovak:
  113.                     return "sk";
  114.                 case LanguageType.Slovenian:
  115.                     return "sl";
  116.                 case LanguageType.Spanish:
  117.                     return "es";
  118.                 case LanguageType.Swedish:
  119.                     return "sv";
  120.                 case LanguageType.Thai:
  121.                     return "th";
  122.                 case LanguageType.Turkish:
  123.                     return "tr";
  124.                 case LanguageType.Ukrainian:
  125.                     return "uk";
  126.                 case LanguageType.Vietnamese:
  127.                     return "vi";
  128.                 default:
  129.                     return "";
  130.             }
  131.         }
  132.     }
  133.     public static class CultureInfoExtension
  134.     {
  135.         public static LanguageType GetLanguageType(this CultureInfo value)
  136.         {
  137.             string name = value.Name.ToLower();
  138.             LanguageType result = LanguageType.English;
  139.             switch (name)
  140.             {
  141.                 case "af":
  142.                 case "af-za":
  143.                     result = LanguageType.English;
  144.                     break;
  145.                 case "sq":
  146.                 case "sq-al":
  147.                     break;
  148.                 case "ar":
  149.                 case "ar-dz":
  150.                 case "ar-bh":
  151.                 case "ar-eg":
  152.                 case "ar-iq":
  153.                 case "ar-jo":
  154.                 case "ar-kw":
  155.                 case "ar-lb":
  156.                 case "ar-ly":
  157.                 case "ar-ma":
  158.                 case "ar-om":
  159.                 case "ar-qa":
  160.                 case "ar-sa":
  161.                 case "ar-sy":
  162.                 case "ar-tn":
  163.                 case "ar-ae":
  164.                 case "ar-ye":
  165.                     result = LanguageType.Arabic;
  166.                     break;
  167.                 case "hy":
  168.                 case "hy-am":
  169.                     break;
  170.                 case "az":
  171.                 case "az-az-cyrl":
  172.                 case "az-az-latn":
  173.                     break;
  174.                 case "eu":
  175.                 case "eu-es":
  176.                     break;
  177.                 case "be":
  178.                 case "be-by":
  179.                     break;
  180.                 case "bg":
  181.                 case "bg-bg":
  182.                     result = LanguageType.Bulgarian;
  183.                     break;
  184.                 case "ca":
  185.                 case "ca-es":
  186.                     result = LanguageType.Catalan;
  187.                     break;
  188.                 case "zh-hk":
  189.                 case "zh-mo":
  190.                 case "zh-cn":
  191.                 case "zh-sg":
  192.                 case "zh-tw":
  193.                 case "zh-chs":
  194.                     result = LanguageType.Chinese_Simplified;
  195.                     break;
  196.                 case "zh-cht":
  197.                     result = LanguageType.Chinese_Traditional;
  198.                     break;
  199.                 case "hr":
  200.                 case "hr-hr":
  201.                     break;
  202.                 case "cs":
  203.                 case "cs-cz":
  204.                     result = LanguageType.Czech;
  205.                     break;
  206.                 case "da":
  207.                 case "da-dk":
  208.                     result = LanguageType.Danish;
  209.                     break;
  210.                 case "div":
  211.                 case "div-mv":
  212.                     break;
  213.                 case "nl":
  214.                 case "nl-be":
  215.                 case "nl-nl":
  216.                     result = LanguageType.Dutch;
  217.                     break;
  218.                 case "en":
  219.                 case "en-au":
  220.                 case "en-bz":
  221.                 case "en-ca":
  222.                 case "en-cb":
  223.                 case "en-ie":
  224.                 case "en-jm":
  225.                 case "en-nz":
  226.                 case "en-ph":
  227.                 case "en-za":
  228.                 case "en-tt":
  229.                 case "en-gb":
  230.                 case "en-us":
  231.                 case "en-zw":
  232.                     result = LanguageType.English;
  233.                     break;
  234.                 case "et":
  235.                 case "et-ee":
  236.                     result = LanguageType.Estonian;
  237.                     break;
  238.                 case "fo":
  239.                 case "fo-fo":
  240.                     break;
  241.                 case "fa":
  242.                 case "fa-ir":
  243.                     break;
  244.                 case "fi":
  245.                 case "fi-fi":
  246.                     result = LanguageType.Finnish;
  247.                     break;
  248.                 case "fr":
  249.                 case "fr-be":
  250.                 case "fr-ca":
  251.                 case "fr-fr":
  252.                 case "fr-lu":
  253.                 case "fr-mc":
  254.                 case "fr-ch":
  255.                     result = LanguageType.French;
  256.                     break;
  257.                 case "gl":
  258.                 case "gl-es":
  259.                     break;
  260.                 case "ka":
  261.                 case "ka-ge":
  262.                     break;
  263.                 case "de":
  264.                 case "de-at":
  265.                 case "de-de":
  266.                 case "de-li":
  267.                 case "de-lu":
  268.                 case "de-ch":
  269.                     result = LanguageType.German;
  270.                     break;
  271.                 case "el":
  272.                 case "el-gr":
  273.                     result = LanguageType.Greek;
  274.                     break;
  275.                 case "gu":
  276.                 case "gu-in":
  277.                     break;
  278.                 case "he":
  279.                 case "he-il":
  280.                     result = LanguageType.Hebrew;
  281.                     break;
  282.                 case "hi":
  283.                 case "hi-in":
  284.                     break;
  285.                 case "hu":
  286.                 case "hu-hu":
  287.                     result = LanguageType.Hungarian;
  288.                     break;
  289.                 case "is":
  290.                 case "is-is":
  291.                     break;
  292.                 case "id":
  293.                 case "id-id":
  294.                     result = LanguageType.Indonesian;
  295.                     break;
  296.                 case "it":
  297.                 case "it-it":
  298.                 case "it-ch":
  299.                     result = LanguageType.Italian;
  300.                     break;
  301.                 case "ja":
  302.                 case "ja-jp":
  303.                     result = LanguageType.Japanese;
  304.                     break;
  305.                 case "kn":
  306.                 case "kn-in":
  307.                     break;
  308.                 case "kk":
  309.                 case "kk-kz":
  310.                     break;
  311.                 case "kok":
  312.                 case "kok-in":
  313.                     break;
  314.                 case "ko":
  315.                 case "ko-kr":
  316.                     result = LanguageType.Korean;
  317.                     break;
  318.                 case "ky":
  319.                 case "ky-kz":
  320.                     break;
  321.                 case "lv":
  322.                 case "lv-lv":
  323.                     result = LanguageType.Latvian;
  324.                     break;
  325.                 case "lt":
  326.                 case "lt-lt":
  327.                     result = LanguageType.Lithuanian;
  328.                     break;
  329.                 case "mk":
  330.                 case "mk-mk":
  331.                     break;
  332.                 case "ms":
  333.                 case "ms-bn":
  334.                 case "ms-my":
  335.                     break;
  336.                 case "mr":
  337.                 case "mr-in":
  338.                     break;
  339.                 case "mn":
  340.                 case "mn-mn":
  341.                     break;
  342.                 case "no":
  343.                     result = LanguageType.Norwegian;
  344.                     break;
  345.                     
  346.                 case "nb-no":
  347.                     break;
  348.                 case "nn-no":
  349.                     break;
  350.                 case "pl": break;
  351.                 case "pl-pl":
  352.                     result = LanguageType.Polish;
  353.                     break;
  354.                 case "pt":
  355.                 case "pt-br":
  356.                 case "pt-pt":
  357.                     result = LanguageType.Portuguese;
  358.                     break;
  359.                 case "pa":
  360.                 case "pa-in":
  361.                     break;
  362.                 case "ro":
  363.                 case "ro-ro":
  364.                     result = LanguageType.Romanian;
  365.                     break;
  366.                 case "ru":
  367.                 case "ru-ru":
  368.                     result = LanguageType.Russian;
  369.                     break;
  370.                 case "sa":
  371.                 case "sa-in":
  372.                     break;
  373.                 case "sr-sp-cyrl":
  374.                 case "sr-sp-latn":
  375.                     break;
  376.                 case "sk":
  377.                 case "sk-sk":
  378.                     result = LanguageType.Slovak;
  379.                     break;
  380.                 case "sl":
  381.                 case "sl-si":
  382.                     result = LanguageType.Slovenian;
  383.                     break;
  384.                 case "es":
  385.                 case "es-ar":
  386.                 case "es-bo":
  387.                 case "es-cl":
  388.                 case "es-co":
  389.                 case "es-cr":
  390.                 case "es-do":
  391.                 case "es-ec":
  392.                 case "es-sv":
  393.                 case "es-gt":
  394.                 case "es-hn":
  395.                 case "es-mx":
  396.                 case "es-ni":
  397.                 case "es-pa":
  398.                 case "es-py":
  399.                 case "es-pe":
  400.                 case "es-pr":
  401.                 case "es-es":
  402.                 case "es-uy":
  403.                 case "es-ve":
  404.                     result = LanguageType.Spanish;
  405.                     break;
  406.                 case "sw":
  407.                 case "sw-ke":
  408.                     break;
  409.                 case "sv":
  410.                 case "sv-fi":
  411.                 case "sv-se":
  412.                     result = LanguageType.Swedish;
  413.                     break;
  414.                 case "syr":
  415.                 case "syr-sy":
  416.                     break;
  417.                 case "ta":
  418.                 case "ta-in":
  419.                     break;
  420.                 case "tt":
  421.                 case "tt-ru":
  422.                     break;
  423.                 case "te":
  424.                 case "te-in":
  425.                     break;
  426.                 case "th":
  427.                 case "th-th":
  428.                     result = LanguageType.Thai;
  429.                     break;
  430.                 case "tr":
  431.                 case "tr-tr":
  432.                     result = LanguageType.Turkish;
  433.                     break;
  434.                 case "uk":
  435.                 case "uk-ua":
  436.                     result = LanguageType.Ukrainian;
  437.                     break;
  438.                 case "ur":
  439.                 case "ur-pk":
  440.                     break;
  441.                 case "uz":
  442.                 case "uz-uz-cyrl":
  443.                 case "uz-uz-latn":
  444.                     break;
  445.                 case "vi":
  446.                 case "vi-vn":
  447.                     result = LanguageType.Vietnamese;
  448.                     break;
  449.                 default:
  450.                     result = LanguageType.AutoDetect;
  451.                     break;
  452.             }
  453.             return result;
  454.         }
  455.     }
  456.     
  457. }

 Kemudian saya membuat class Utility untuk memudahkan memanggil fungsi API Translatornya

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Configuration;
  6. using System.Globalization;
  7. namespace MyResourceManager
  8. {
  9.     public static class Utils
  10.     {
  11.         /// <summary>
  12.         /// Application ID untuk kebutuhan Service API Translator, APP ID dapat dibuat dari link http://www.bing.com/developers/appids.aspx
  13.         /// </summary>
  14.         private static string _AppId = ConfigurationManager.AppSettings["MSTranslatorAppId"].ToString();
  15.         /// <summary>
  16.         /// default kode bahasa ResourceKey valuenya dapat didapat dari LanguageTypeExtension.GetLanguageCode()
  17.         /// </summary>
  18.         private static string _ResourceKeyLanguage = ConfigurationManager.AppSettings["ResourceKeyLanguage"].ToString();
  19.         public static string ResourceKeyLanguage
  20.         {
  21.             get
  22.             {
  23.                 return _ResourceKeyLanguage;
  24.             }
  25.         }
  26.         public static string AppId
  27.         {
  28.             get
  29.             {
  30.                 return _AppId;
  31.             }
  32.         }
  33.         public static string Translate(string resourceKey, LanguageType from, LanguageType to)
  34.         {
  35.             if (from.Equals(to)) // Skip jika translate ke bahasa yg sama;
  36.                 return resourceKey;
  37.             string result = string.Empty;
  38.             using (MSTranslator.LanguageServiceClient client = new MSTranslator.LanguageServiceClient())
  39.             {
  40.                 result = client.Translate(_AppId, resourceKey, from.GetLanguageCode(), to.GetLanguageCode(), "text/plain", "general");
  41.             }
  42.             return result;
  43.         }
  44.         public static string Translate(string resourceKey, CultureInfo from, CultureInfo to)
  45.         {
  46.             LanguageType fromLang = from.GetLanguageType();
  47.             LanguageType toLang = to.GetLanguageType();
  48.             return Translate(resourceKey, fromLang, toLang);
  49.         }
  50.     }
  51. }

Kemudian implementasi ResourceManagernya (disini saya tidak menjelaskan lebih detail, beberapa code saya ambil dari contoh http://msdn.microsoft.com/en-us/library/aa905797.aspx.  

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Resources;
  6. using System.Globalization;
  7. using System.Web.Compilation;
  8. using System.Collections.Specialized;
  9. namespace MyResourceManager
  10. {
  11.     public class DisposableBaseType : IDisposable
  12.     {
  13.         private bool m_Disposed;
  14.         protected bool Disposed
  15.         {
  16.             get
  17.             {
  18.                 lock (this)
  19.                 {
  20.                     return m_Disposed;
  21.                 }
  22.             }
  23.         }
  24.         #region IDisposable Members
  25.         public void Dispose()
  26.         {
  27.             lock (this)
  28.             {
  29.                 if (m_Disposed == false)
  30.                 {
  31.                     Cleanup();
  32.                     m_Disposed = true;
  33.                     GC.SuppressFinalize(this);
  34.                 }
  35.             }
  36.         }
  37.         #endregion
  38.         protected virtual void Cleanup()
  39.         {
  40.             // override to provide cleanup
  41.         }
  42.         ~DisposableBaseType()
  43.         {
  44.             Cleanup();
  45.         }
  46.     }
  47.     public class MyResourceReader : DisposableBaseType, IResourceReader, IEnumerable<KeyValuePair<string, object>>
  48.     {
  49.         private ListDictionary _listDic;
  50.         public MyResourceReader(ListDictionary dic)
  51.         {
  52.             this._listDic = dic;
  53.         }
  54.         #region IResourceReader Members
  55.         public void Close()
  56.         {
  57.             this.Dispose();
  58.         }
  59.         public System.Collections.IDictionaryEnumerator GetEnumerator()
  60.         {
  61.             if (Disposed)
  62.                 throw new ObjectDisposedException("MyResourceReader object is already disposed.");
  63.             return this._listDic.GetEnumerator();
  64.         }
  65.         #endregion
  66.         #region IEnumerable Members
  67.         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  68.         {
  69.             if (Disposed)
  70.                 throw new ObjectDisposedException("MyResourceReader object is already disposed.");
  71.             return this._listDic.GetEnumerator();
  72.         }
  73.         #endregion
  74.         protected override void Cleanup()
  75.         {
  76.             try
  77.             {
  78.                 this._listDic = null;
  79.             }
  80.             finally
  81.             {
  82.                 base.Cleanup();
  83.             }
  84.         }
  85.         #region IEnumerable<KeyValuePair<string,object>> Members
  86.         IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator()
  87.         {
  88.             if (Disposed)
  89.                 throw new ObjectDisposedException("MyResourceReader object is already disposed.");
  90.            return this._listDic.GetEnumerator() as IEnumerator<KeyValuePair<string, object>>;
  91.         }
  92.         #endregion
  93.     }
  94.     public class MyResourceProvider : DisposableBaseType, IResourceProvider
  95.     {
  96.         private string classKey;
  97.         private Dictionary<string, Dictionary<string, string>> resourceCache = new Dictionary<string, Dictionary<string, string>>();
  98.         private CultureInfo resourceKeyLanguage = new CultureInfo(Utils.ResourceKeyLanguage);
  99.         public MyResourceProvider(string classKey)
  100.         {
  101.             this.classKey = classKey;
  102.         }
  103.         #region IResourceProvider Members
  104.         public object GetObject(string resourceKey, CultureInfo culture)
  105.         {
  106.             if (Disposed)
  107.                 throw new ObjectDisposedException("MyResourceProvider object is already disposed.");
  108.             if (string.IsNullOrEmpty(resourceKey))
  109.                 throw new ArgumentNullException("resourceKey");
  110.             if (culture == null)
  111.                 culture = CultureInfo.CurrentUICulture;
  112.             if (string.IsNullOrEmpty(culture.Name))
  113.                 culture = System.Globalization.CultureInfo.CurrentUICulture;
  114.             string resourceValue = null;
  115.             Dictionary<string, string> resCacheByCulture = null;
  116.             if (resourceCache.ContainsKey(culture.Name))
  117.             {
  118.                 resCacheByCulture = resourceCache[culture.Name];
  119.                 if (resCacheByCulture.ContainsKey(resourceKey))
  120.                     resourceValue = resCacheByCulture[resourceKey];
  121.             }
  122.             if (resourceValue == null)
  123.             {
  124.                 resourceValue = Utils.Translate(resourceKey, resourceKeyLanguage, culture);
  125.                 // add this result to the cache
  126.                 // find the dictionary for this culture
  127.                 // add this key/value pair to the inner dictionary
  128.                 lock (this)
  129.                 {
  130.                     if (resCacheByCulture == null)
  131.                     {
  132.                         resCacheByCulture = new Dictionary<string, string>();
  133.                         resourceCache.Add(culture.Name, resCacheByCulture);
  134.                     }
  135.                     resCacheByCulture.Add(resourceKey, resourceValue);
  136.                 }
  137.             }
  138.             return resourceValue;
  139.         }
  140.         public IResourceReader ResourceReader
  141.         {
  142.             get
  143.             {
  144.                 if (Disposed)
  145.                     throw new ObjectDisposedException("MyResourceProvider object is already disposed.");
  146.                 // this is required for implicit resources
  147.                 // this is also used for the expression editor sheet
  148.                 ListDictionary resourceDictionary = new ListDictionary();
  149.                 return new MyResourceReader(resourceDictionary);
  150.             }
  151.         }
  152.         #endregion
  153.         protected override void Cleanup()
  154.         {
  155.             try
  156.             {
  157.                 this.resourceCache.Clear();
  158.             }
  159.             finally
  160.             {
  161.                 base.Cleanup();
  162.             }
  163.         }
  164.     }
  165.     public class MyResourceProviderFactory : ResourceProviderFactory
  166.     {
  167.         public override IResourceProvider CreateGlobalResourceProvider(string classKey)
  168.         {
  169.             return new MyResourceProvider(classKey);
  170.         }
  171.         public override IResourceProvider CreateLocalResourceProvider(string virtualPath)
  172.         {
  173.             string classKey = virtualPath;
  174.             if (!string.IsNullOrEmpty(virtualPath))
  175.             {
  176.                 virtualPath = virtualPath.Remove(0, 1);
  177.                 classKey = virtualPath.Remove(0, virtualPath.IndexOf('/') + 1);
  178.             }
  179.             return new MyResourceProvider(classKey);
  180.         }
  181.     }
  182. }


Kemudian tambahan web.config nya

Code Snippet
  1. .
  2. .
  3. .
  4. <appSettings>
  5.     <!-- default kode bahasa ResourceKey valuenya dapat didapat dari LanguageTypeExtension.GetLanguageCode() -->
  6.     <add key="ResourceKeyLanguage" value="en" />
  7.     <!-- Application ID untuk kebutuhan Service API Translator, APP ID dapat dibuat dari link http://www.bing.com/developers/appids.aspx -->
  8.     <add key="MSTranslatorAppId" value="2FF28BD209C6653904A8307F0BA50E1D97E862B0"/>
  9.   </appSettings>
  10.   <system.web>
  11.     <!-- uiCulture untuk default tampilan bahsa di UInya -->
  12.     <globalization culture="en-US" uiCulture="en-US" resourceProviderFactoryType="MyResourceManager.MyResourceProviderFactory, MyResourceManager" />
  13.    .
  14.    .
  15.    .
  16.    .

Pada contoh ini ada beberapa configurasi yg perlu kita ketahui

  1. Pada AppSetting ResourceKeyLanguage ini digunakan untuk default bahasa ResourceKey nya. Setiap kita membuat resourceKey, musti dalam bahasa yg diset pada ResourceKeyLanguage.
  2. Pada AppSetting MSTranslatorAppId, Application ID harus diset untuk mendapatkannya harus register terlebih dahulu pada link http://www.bing.com/developers/appids.aspx

Berhubung waktu terbatas, sepertinya cukup untuk sekian dulu... Big Smile


 

Share this post: | | | |

Comments

Anwar Minarso said:

Sebelumnya saya telah membuat contoh Custom ResourceManger dengan implementasi API Bing Translator pada

# August 22, 2011 9:53 PM