Anwar Minarso

See also: Other Geeks@INDC

Multilingual ResourceManager dgn Auto Translate (Part II)

Sebelumnya saya telah membuat contoh Custom ResourceManger dengan implementasi API Bing Translator pada post Multilingual ResourceManager dgn Auto Translate (Part I).  

Kali ini, saya akan tune up agar performance lebih baik dan juga lebih mudah dimaintain. Adapun yg di Tune Up adalah sbb :

  1. Menggunakan database
    ResourceManager akan menarik resource data cache terlebih dahulu, jika tidak ada menarik ke database, jika resource tidak ditemukan, maka secara automatis mentranslate dgn service Translator dan menyimpannya kedalam database dan di cache
  2. Memudahkan Maintain
    Dengan menggunakan database akan memudahkan kita memaintain data output translatenya, jika translatornya salah.

source code dapat didownload di sini

Ok, kita lanjut ...

Pertama2 membuat class untuk store database (dengan LinqToSql)

Code Snippet
  1. [Table(Name = "ResourceData")]
  2.     public class ResourceData
  3.     {
  4.         [Column(Name = "ResourceID", CanBeNull = false, IsDbGenerated = true, IsPrimaryKey = true, AutoSync = AutoSync.OnInsert)]
  5.         public long ResourceID { get; set; }
  6.         [Column(Name = "ResourceType", DbType = "NVARCHAR(1000) NOT NULL", CanBeNull = false)]
  7.         public string ResourceType { get; set; }
  8.         [Column(Name = "ResourceKey", DbType = "NVARCHAR(MAX) NOT NULL", CanBeNull = false)]
  9.         public string ResourceKey { get; set; }
  10.         [Column(Name = "FromLanguageCode", DbType = "VARCHAR(20) NOT NULL", CanBeNull = false)]
  11.         public string FromLanguageCode { get; set; }
  12.         [Column(Name = "ToLanguageCode", DbType = "VARCHAR(20) NOT NULL", CanBeNull = false)]
  13.         public string ToLanguageCode { get; set; }
  14.         [Column(Name = "ResourceValue", DbType = "NVARCHAR(MAX) NOT NULL", CanBeNull = false)]
  15.         public string ResourceValue { get; set; }
  16.     }

Kemudian membuat DataContextnya (dengan default connectionStringName nya adalah "MyResourceManager")

Code Snippet
  1. public class ResourceDataContext : DataContext
  2.     {
  3.         private static string ConnectionString = ConfigurationManager.ConnectionStrings["MyResourceManager"].ConnectionString;
  4.         private static AttributeMappingSource mappingSource = new AttributeMappingSource();
  5.         public Table<ResourceData> Resources
  6.         {
  7.             get
  8.             {
  9.                 return GetTable<ResourceData>();
  10.             }
  11.         }
  12.         public ResourceDataContext()
  13.             : base(ConnectionString, mappingSource)
  14.         {
  15.         }
  16.         /// <summary>
  17.         /// attribute [MethodImpl(MethodImplOptions.Synchronized)] memaksa agar fungsi ini menjadi thread-safe
  18.         /// </summary>
  19.         [MethodImpl(MethodImplOptions.Synchronized)]
  20.         public ResourceData GetByResourceKey(string ResourceType, string ResourceKey, string FromLanguageCode, string ToLanguageCode)
  21.         {
  22.             var query = from r in Resources
  23.                         where r.ResourceType.Equals(ResourceType) && r.ResourceKey.Equals(ResourceKey) && r.FromLanguageCode.Equals(FromLanguageCode) && r.ToLanguageCode.Equals(ToLanguageCode)
  24.                        select r;
  25.             var data = query.ToArray(); // pada sql 2005 query equal operator tidak case sensitive
  26.             return data.FirstOrDefault(t => t.ResourceKey.Equals(ResourceKey)); // memaksa agar case sensitive
  27.         }
  28.         [MethodImpl(MethodImplOptions.Synchronized)]
  29.         public ListDictionary GetByFromLanguageCodeToLanguageCode(string ResourceType, string FromLanguageCode, string ToLanguageCode)
  30.         {
  31.             var query = from r in Resources
  32.                         where r.ResourceType.Equals(ResourceType) && r.FromLanguageCode.Equals(FromLanguageCode) && r.ToLanguageCode.Equals(ToLanguageCode)
  33.                         select new { r.ResourceKey, r.ResourceValue };
  34.             ListDictionary dic = new ListDictionary();
  35.             foreach (var result in query)
  36.                 dic.Add(result.ResourceKey, result.ResourceValue);
  37.             return dic;
  38.         }
  39.     }


 Kemudian update coding dibawah ini pada class MyResourceProvider method GetObject

Code Snippet
  1. public object GetObject(string resourceKey, CultureInfo culture)
  2.         {
  3.             if (Disposed)
  4.                 throw new ObjectDisposedException("MyResourceProvider object is already disposed.");
  5.             if (string.IsNullOrEmpty(resourceKey))
  6.                 throw new ArgumentNullException("resourceKey");
  7.             if (culture == null)
  8.                 culture = CultureInfo.CurrentUICulture;
  9.             if (string.IsNullOrEmpty(culture.Name))
  10.                 culture = System.Globalization.CultureInfo.CurrentUICulture;
  11.             string resourceValue = null;
  12.             Dictionary<string, string> resCacheByCulture = null;
  13.             if (resourceCache.ContainsKey(culture.Name))
  14.             {
  15.                 resCacheByCulture = resourceCache[culture.Name];
  16.                 if (resCacheByCulture.ContainsKey(resourceKey))
  17.                     resourceValue = resCacheByCulture[resourceKey];
  18.             }
  19.             if (resourceValue == null)
  20.             {
  21.                 using (ResourceDataContext ctxt = new ResourceDataContext())
  22.                 {
  23.                     // Create Database jika tidak ada
  24.                     if (!ctxt.DatabaseExists())
  25.                         ctxt.CreateDatabase();
  26.                     string fromLanguageCode = resourceKeyLanguage.GetLanguageType().GetLanguageCode();
  27.                     string toLanguageCode = culture.GetLanguageType().GetLanguageCode();
  28.                     // Tarik data Resource
  29.                     ResourceData data = ctxt.GetByResourceKey(classKey, resourceKey, fromLanguageCode, toLanguageCode);
  30.                     if (data == null)
  31.                     {
  32.                         // jika data tidak ada, menarik service API
  33.                         resourceValue = Utils.Translate(resourceKey, resourceKeyLanguage.GetLanguageType(), culture.GetLanguageType());
  34.                         data = new ResourceData();
  35.                         data.ResourceType = classKey;
  36.                         data.ResourceKey = resourceKey;
  37.                         data.FromLanguageCode = fromLanguageCode;
  38.                         data.ToLanguageCode = toLanguageCode;
  39.                         data.ResourceValue = resourceValue;
  40.                         // Insert data
  41.                         ctxt.Resources.InsertOnSubmit(data);
  42.                         ctxt.SubmitChanges();
  43.                     }
  44.                     else
  45.                         resourceValue = data.ResourceValue;
  46.                 }
  47.                 // add this result to the cache
  48.                 // find the dictionary for this culture
  49.                 // add this key/value pair to the inner dictionary
  50.                 lock (this)
  51.                 {
  52.                     if (resCacheByCulture == null)
  53.                     {
  54.                         resCacheByCulture = new Dictionary<string, string>();
  55.                         resourceCache.Add(culture.Name, resCacheByCulture);
  56.                     }
  57.                     resCacheByCulture.Add(resourceKey, resourceValue);
  58.                 }
  59.             }
  60.             return resourceValue;
  61.         }

 Dan yang terakhir tambahakn ConnectionString pada web.config

Code Snippet
  1. <connectionStrings>
  2.     <add name="MyResourceManager" connectionString="Data Source=.\SQL2005;Initial Catalog=MyResourceManagerDB;User ID=sa;Password=12345" providerName="System.Data.SqlCLient"/>
  3.   </connectionStrings>

Rename DataSource, User dan password, sesuai environment kalian...

Semoga bermanfaat Big Smile 

Share this post: | | | |

Comments

No Comments