Database storage extension for localized resources of the DDD development Framework ABP

Source: Internet
Author: User



In the previous article, "Localization/multi-lingual support for the DDD development Framework ABP", we know that the localization resource store in the ABP development framework can take an XML file, a ResX resource file, and an extended interface for other custom storage methods. The ABP framework implements the first two methods by default, and the database storage method needs to be expanded by itself, presumably because database storage involves physical and warehousing specifics and is not suitable for basic frameworks.



One of the most obvious benefits of storing localized resources in a database is the ease of modification, especially for database-based applications that provide a unified maintenance interface. Next, we'll step through the implementation of storing localized resources in the database.


The first step is to establish the entity


If we are storing resources in XML, we need to build XML resource files and how many resource files we need to build to support the number of languages. In this case, storing the resource text in a database naturally requires the entity to be created, and then the entity's read operation is realized.



In order to store resources, we need to create an entity:


 
 1 public class DBLocalization : Entity
 2 {
 3     [Required]
 4     [StringLength(10)]
 5     public virtual string Culture { get; set; }
 6     [Required]
 7     [StringLength(50)]
 8     public virtual string Name { get; set; }
 9     [Required]
10     public virtual string Value { get; set; }
11 }


The culture attribute is the language code, such as EN, ZH-TW, ZH-CN and so on. The Name property is the names, and the Value property is the corresponding text. The base class entity is the generic domain entity class provided by the ABP framework, which has an integer ID by default and implements the IEntity interface.


Second step to establish Domain Services


Domain Services provide data manipulation of entities, such as the acquisition of language types and language dictionaries.


 
1 public class DBLocalizationManager : DomainService
 2 {
 3     private readonly IRepository<DBLocalization> _localizationRepository; 
 4     public DBLocalizationManager(IRepository<DBLocalization> localizationRepository) 
 5     {
 6         _localizationRepository = localizationRepository;
 7     }
 8     public List<CultureInfo> GetCultures() 
 9     {
10         return _localizationRepository.GetAllList()
11         .Select(p => new CultureInfo(p.Culture))
12         .Distinct()
13         .ToList<CultureInfo>();
14     }
15     public List<DBLocalization> GetDictionary()
16     {
17         return _localizationRepository.GetAllList();
18     }
19 }


Where irepository<dblocalization> is injected in a constructor-function manner.


The third step is to implement the localized resource Interface (Ilocalizationsource)


Ilocalizationsource is the core interface of the localization framework, and the interface methods include:



Name: Resource Names,
Initialize (): Initialization method, called by ABP when registering
String GetString (string name) obtains text by name
Ireadonlylist<localizedstring> getallstrings () Get a full list of dictionaries for the current language



ABP already has three classes that implement the Ilocalizationsource interface: Nulllocalizationsource, Resourcefilelocalizationsource, and Dictionarybasedlocalizationsource.



Storing the resource text in the database, accessing the database every time the text is obtained, but based on performance considerations, it is obvious that the resource text is loaded into memory at the time of initialization and should be a better way. Since Dictionarybasedlocalizationsource has implemented a common approach to memory dictionaries, we don't need to write another dblocalizationsource. Looking at the Dictionarybasedlocalizationsource code, you can see that its constructor needs to pass in an instance of Ilocalizationdictionaryprovider, which is used to get the details of the localized dictionary.
Next we set up a class to implement the Ilocalizationdictionaryprovider interface:


 
 1 public class DBLocalizationDictionaryProvider : ILocalizationDictionaryProvider
 2 {
 3     private DBLocalizationManager _dbLocalizationManager;
 4     public IEnumerable<LocalizationDictionaryInfo> GetDictionaries(string sourceName)
 5     {
 6         if (_dbLocalizationManager == null) 
 7         {
 8             if (IocManager.Instance.IsRegistered<DBLocalizationManager>())
 9             {
10             _dbLocalizationManager = IocManager.Instance.Resolve<DBLocalizationManager>();
11             }
12         }
13         var dictionaries = new List<LocalizationDictionaryInfo>();
14         foreach (var culture in _dbLocalizationManager.GetCultures())
15         {
16             dictionaries.Add(
17                 new LocalizationDictionaryInfo(
18                     DBLocalizationDictionary.Build(culture.Name,
19                     _dbLocalizationManager.GetDictionary()) ,
20                     isDefault: culture.Name == ZeroConsts.DefaultLanguage
21                 )
22             );
23         }
24         return dictionaries;
25     }
26 }


This class implements the Getdictionaries method of the interface and obtains the Dictionary object dblocalizationdictionary. The method first uses the dependency injection container to get an instance of Idblocalizationmanager automatically.



The following is the implementation code for the Dblocalizationdictionary dictionary class:


 
 1 public class DBLocalizationDictionary : LocalizationDictionary
 2 {
 3     private DBLocalizationDictionary(CultureInfo cultureInfo)
 4         : base(cultureInfo)
 5     {
 6     }
 7     public static DBLocalizationDictionary Build(string cultureName, List<DBLocalization> dictList)
 8     {
 9         try
10         {
11             var dictionary = new DBLocalizationDictionary(new CultureInfo(cultureName));
12             var dublicateNames = new List<string>();
13             if (dictList != null && dictList.Count>0)
14             {
15                 foreach (DBLocalization item in dictList.FindAll(c => c.Culture == cultureName))
16                 {
17                     if (string.IsNullOrEmpty(item.Name))
18                     {
19                         throw new AbpException("name of a dictionary is empty in given data.");
20                     }
21                     if (dictionary.Contains(item.Name))
22                     {
23                         dublicateNames.Add(item.Name);
24                     }
25                     dictionary[item.Name] = item.Value.NormalizeLineEndings();
26                 }
27             }
28             if (dublicateNames.Count > 0)
29             {
30                 throw new AbpException("A dictionary can not contain same key twice. There are some duplicated names: " + dublicateNames.JoinAsString(", "));
31             }
32             return dictionary;
33         }
34         catch (Exception ex)
35         {
36             throw new AbpException("Invalid localization data format! ", ex);
37         }
38     }
39 }
Fourth Step registration Resources


In a module where multilingual localization is required, we can register resources in the module's Preinitialize method. A module can add multiple resources to the Configuration.Localization.Sources collection, as long as the Ilocalizationsource interface is implemented.


 
1 public override void PreInitialize()
2 {
3     Configuration.Localization.Sources.Add(
4         new DictionaryBasedLocalizationSource("Zero", new DBLocalizationDictionaryProvider()));
5 }


Here, the localization of resources stored in the database is basically all implemented, and the rest is the development community in the face of localized resources for the maintenance of the increase and deletion.



Database storage extension for localized resources of the DDD development Framework ABP


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.