NopCommerce源码架构详解-Localization多语言本地化实现源码分析

NopCommerce为了语言的国际化,它支持多国家的语言,你可以系统在添加任意多个国家语言。

NopCommerce源码架构详解概述

文章目录

概述

NopCommerce源码架构详解-Localization多语言本地化实现源码分析。

内容

NopCommerce为了语言的国际化,它支持多国家的语言,你可以系统在添加任意多个国家语言。我之前的文章NopCommerce源码架构详解-使用FluentValidation创建Model自定义Validator验证源码分析就有提高到过nop的-Localization多语言。今天我就来详细介绍一下Nop是怎么实现的Localization多语言本地化。

首先,来看看Nop中与语言相关的表。

Nop主要有两个表来存储语言,分别是LocaleStringResource(每个语言相关明细–资源字符串)和Language(语言种类)

LocaleStringResource表:

SELECT TOP 1000 [Id]
      ,[LanguageId]
      ,[ResourceName]
      ,[ResourceValue]
  FROM [LocaleStringResource]
2020-04-24-00-14-50

Language表:

SELECT TOP 1000 [Id]
      ,[Name]
      ,[LanguageCulture]
      ,[UniqueseoCode]
      ,[FlagImageFileName]
      ,[Rtl]
      ,[LimitedToStores]
      ,[DefaultCurrencyId]
      ,[Published]
      ,[DisplayOrder]
  FROM [Language]
2020-04-24-00-15-05

接下来我们来通过一个验证提示信息类BlogPostValidator来看看这个多语言是怎么实现的。

BlogPostValidator.cs:

public class BlogPostValidator : AbstractValidator<BlogPostModel>
{
    public BlogPostValidator(ILocalizationService localizationService)
    {
        RuleFor(x => x.Title)
            .NotEmpty()
            .WithMessage(localizationService.GetResource("Admin.ContentManagement.Blog.BlogPosts.Fields.Title.Required"));

        RuleFor(x => x.Body)
            .NotEmpty()
            .WithMessage(localizationService.GetResource("Admin.ContentManagement.Blog.BlogPosts.Fields.Body.Required"));
    }
}
2020-04-24-00-15-18

接口ILocalizationService的真正实现类是Nop.Services.Localization.LocalizationService,其中里面的方法GetResource为:

public virtual string GetResource(string resourceKey, int languageId,
            bool logIfNotFound = true, string defaultValue = "", bool returnEmptyIfNotFound = false)
{
    string result = string.Empty;
    if (resourceKey == null)
        resourceKey = string.Empty;
    resourceKey = resourceKey.Trim().ToLowerInvariant();
    if (_localizationSettings.LoadAllLocaleRecordsOnStartup)
    {
        //load all records (we know they are cached)
        var resources = GetAllResourceValues(languageId);
        if (resources.ContainsKey(resourceKey))
        {
            result = resources[resourceKey].Value;
        }
    }
    else
    {
        //gradual loading
        string key = string.Format(LOCALSTRINGRESOURCES_BY_RESOURCENAME_KEY, languageId, resourceKey);
        string lsr = _cacheManager.Get(key, () =>
        {
            var query = from l in _lsrRepository.Table
                        where l.ResourceName == resourceKey
                        && l.LanguageId == languageId
                        select l.ResourceValue;
            return query.FirstOrDefault();
        });

        if (lsr != null) 
            result = lsr;
    }
    if (String.IsNullOrEmpty(result))
    {
        if (logIfNotFound)
            _logger.Warning(string.Format("Resource string ({0}) is not found. Language ID = {1}", resourceKey, languageId));

        if (!String.IsNullOrEmpty(defaultValue))
        {
            result = defaultValue;
        }
        else
        {
            if (!returnEmptyIfNotFound)
                result = resourceKey;
        }
    }
    return result;
}
public virtual string GetResource(string resourceKey)
{
    if (_workContext.WorkingLanguage != null)
        return GetResource(resourceKey, _workContext.WorkingLanguage.Id);

    return "";
}
2020-04-24-00-15-39

接口IWorkContext真正实现类是Nop.Web.Framework.WebWorkContext,里面有一个获取语言的属性。

public virtual Language WorkingLanguage
{
    get
    {
        if (_cachedLanguage != null)
            return _cachedLanguage;

        Language detectedLanguage = null;
        if (_localizationSettings.SeoFriendlyUrlsForLanguagesEnabled)
        {
            //从URL中获取语言
            detectedLanguage = GetLanguageFromUrl();
        }
        if (detectedLanguage == null && _localizationSettings.AutomaticallyDetectLanguage)
        {
            //get language from browser settings
            //but we do it only once
            if (!this.CurrentCustomer.GetAttribute<bool>(SystemCustomerAttributeNames.LanguageAutomaticallyDetected, 
                _genericAttributeService, _storeContext.CurrentStore.Id))
            {
                detectedLanguage = GetLanguageFromBrowserSettings();
                if (detectedLanguage != null)
                {
                    _genericAttributeService.SaveAttribute(this.CurrentCustomer, SystemCustomerAttributeNames.LanguageAutomaticallyDetected,
                         true, _storeContext.CurrentStore.Id);
                }
            }
        }
        if (detectedLanguage != null)
        {
            //the language is detected. now we need to save it
            if (this.CurrentCustomer.GetAttribute<int>(SystemCustomerAttributeNames.LanguageId,
                _genericAttributeService, _storeContext.CurrentStore.Id) != detectedLanguage.Id)
            {
                _genericAttributeService.SaveAttribute(this.CurrentCustomer, SystemCustomerAttributeNames.LanguageId,
                    detectedLanguage.Id, _storeContext.CurrentStore.Id);
            }
        }

        var allLanguages = _languageService.GetAllLanguages(storeId: _storeContext.CurrentStore.Id);
        //find current customer language
        var languageId = this.CurrentCustomer.GetAttribute<int>(SystemCustomerAttributeNames.LanguageId,
            _genericAttributeService, _storeContext.CurrentStore.Id);
        var language = allLanguages.FirstOrDefault(x => x.Id == languageId);
        if (language == null)
        {
            //如果没有指定语言,默认返回系统中的第一种语言
            language = allLanguages.FirstOrDefault();
        }
        if (language == null)
        {
            //it not specified, then return the first found one
            language = _languageService.GetAllLanguages().FirstOrDefault();
        }

        //cache
        _cachedLanguage = language;
        return _cachedLanguage;
    }
    set
    {
        var languageId = value != null ? value.Id : 0;
        _genericAttributeService.SaveAttribute(this.CurrentCustomer,
            SystemCustomerAttributeNames.LanguageId,
            languageId, _storeContext.CurrentStore.Id);

        //reset cache
        _cachedLanguage = null;
    }
}
原文出处:蓝狐软件工作室【蓝狐】

原文链接:http://m.lanhusoft.com/Article/349.html

本文观点不代表 .Net中文网 立场,转载请联系原作者。

发表评论

登录后才能评论