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 :
- 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 - 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
- [Table(Name = "ResourceData")]
- public class ResourceData
- {
- [Column(Name = "ResourceID", CanBeNull = false, IsDbGenerated = true, IsPrimaryKey = true, AutoSync = AutoSync.OnInsert)]
- public long ResourceID { get; set; }
- [Column(Name = "ResourceType", DbType = "NVARCHAR(1000) NOT NULL", CanBeNull = false)]
- public string ResourceType { get; set; }
- [Column(Name = "ResourceKey", DbType = "NVARCHAR(MAX) NOT NULL", CanBeNull = false)]
- public string ResourceKey { get; set; }
- [Column(Name = "FromLanguageCode", DbType = "VARCHAR(20) NOT NULL", CanBeNull = false)]
- public string FromLanguageCode { get; set; }
- [Column(Name = "ToLanguageCode", DbType = "VARCHAR(20) NOT NULL", CanBeNull = false)]
- public string ToLanguageCode { get; set; }
- [Column(Name = "ResourceValue", DbType = "NVARCHAR(MAX) NOT NULL", CanBeNull = false)]
- public string ResourceValue { get; set; }
- }
Kemudian membuat DataContextnya (dengan default connectionStringName nya adalah "MyResourceManager")
Code Snippet
- public class ResourceDataContext : DataContext
- {
- private static string ConnectionString = ConfigurationManager.ConnectionStrings["MyResourceManager"].ConnectionString;
- private static AttributeMappingSource mappingSource = new AttributeMappingSource();
- public Table<ResourceData> Resources
- {
- get
- {
- return GetTable<ResourceData>();
- }
- }
- public ResourceDataContext()
- : base(ConnectionString, mappingSource)
- {
- }
- /// <summary>
- /// attribute [MethodImpl(MethodImplOptions.Synchronized)] memaksa agar fungsi ini menjadi thread-safe
- /// </summary>
- [MethodImpl(MethodImplOptions.Synchronized)]
- public ResourceData GetByResourceKey(string ResourceType, string ResourceKey, string FromLanguageCode, string ToLanguageCode)
- {
- var query = from r in Resources
- where r.ResourceType.Equals(ResourceType) && r.ResourceKey.Equals(ResourceKey) && r.FromLanguageCode.Equals(FromLanguageCode) && r.ToLanguageCode.Equals(ToLanguageCode)
- select r;
- var data = query.ToArray(); // pada sql 2005 query equal operator tidak case sensitive
- return data.FirstOrDefault(t => t.ResourceKey.Equals(ResourceKey)); // memaksa agar case sensitive
- }
- [MethodImpl(MethodImplOptions.Synchronized)]
- public ListDictionary GetByFromLanguageCodeToLanguageCode(string ResourceType, string FromLanguageCode, string ToLanguageCode)
- {
- var query = from r in Resources
- where r.ResourceType.Equals(ResourceType) && r.FromLanguageCode.Equals(FromLanguageCode) && r.ToLanguageCode.Equals(ToLanguageCode)
- select new { r.ResourceKey, r.ResourceValue };
- ListDictionary dic = new ListDictionary();
- foreach (var result in query)
- dic.Add(result.ResourceKey, result.ResourceValue);
- return dic;
- }
- }
Kemudian update coding dibawah ini pada class MyResourceProvider method GetObject
Code Snippet
- public object GetObject(string resourceKey, CultureInfo culture)
- {
- if (Disposed)
- throw new ObjectDisposedException("MyResourceProvider object is already disposed.");
- if (string.IsNullOrEmpty(resourceKey))
- throw new ArgumentNullException("resourceKey");
- if (culture == null)
- culture = CultureInfo.CurrentUICulture;
- if (string.IsNullOrEmpty(culture.Name))
- culture = System.Globalization.CultureInfo.CurrentUICulture;
- string resourceValue = null;
- Dictionary<string, string> resCacheByCulture = null;
- if (resourceCache.ContainsKey(culture.Name))
- {
- resCacheByCulture = resourceCache[culture.Name];
- if (resCacheByCulture.ContainsKey(resourceKey))
- resourceValue = resCacheByCulture[resourceKey];
- }
- if (resourceValue == null)
- {
- using (ResourceDataContext ctxt = new ResourceDataContext())
- {
- // Create Database jika tidak ada
- if (!ctxt.DatabaseExists())
- ctxt.CreateDatabase();
- string fromLanguageCode = resourceKeyLanguage.GetLanguageType().GetLanguageCode();
- string toLanguageCode = culture.GetLanguageType().GetLanguageCode();
- // Tarik data Resource
- ResourceData data = ctxt.GetByResourceKey(classKey, resourceKey, fromLanguageCode, toLanguageCode);
- if (data == null)
- {
- // jika data tidak ada, menarik service API
- resourceValue = Utils.Translate(resourceKey, resourceKeyLanguage.GetLanguageType(), culture.GetLanguageType());
- data = new ResourceData();
- data.ResourceType = classKey;
- data.ResourceKey = resourceKey;
- data.FromLanguageCode = fromLanguageCode;
- data.ToLanguageCode = toLanguageCode;
- data.ResourceValue = resourceValue;
- // Insert data
- ctxt.Resources.InsertOnSubmit(data);
- ctxt.SubmitChanges();
- }
- else
- resourceValue = data.ResourceValue;
- }
- // add this result to the cache
- // find the dictionary for this culture
- // add this key/value pair to the inner dictionary
- lock (this)
- {
- if (resCacheByCulture == null)
- {
- resCacheByCulture = new Dictionary<string, string>();
- resourceCache.Add(culture.Name, resCacheByCulture);
- }
- resCacheByCulture.Add(resourceKey, resourceValue);
- }
- }
- return resourceValue;
- }
Dan yang terakhir tambahakn ConnectionString pada web.config
Code Snippet
- <connectionStrings>
- <add name="MyResourceManager" connectionString="Data Source=.\SQL2005;Initial Catalog=MyResourceManagerDB;User ID=sa;Password=12345" providerName="System.Data.SqlCLient"/>
- </connectionStrings>
Rename DataSource, User dan password, sesuai environment kalian...
Semoga bermanfaat