zoukankan      html  css  js  c++  java
  • NOP源码分析 八---set的存储

    我们已经把ISetting的基本实现都过了一遍,但好像它的值如何取出来的,还不知道。

    其实通过上节我们可知道 ,最终他是通过SettingService.cs类GetAllSettingsCached方法进行。内部有如下代码:

    var query = from s in _settingRepository.TableNoTracking
                                orderby s.Name, s.StoreId
                                select s;

    AsNoTracking是EF的一个功能,就是不跟踪状态。只读的情况下用它提高效率,可百度。最终是通过settingRepository从数据库取出的数值。当然表是Setting表,通过声明private readonly IRepository<Setting> _settingRepository; 就可知道。

    好了,现在所有知道所有的ISetting的继承子类  都是通过读取数据库的Setting表得到的数值。

    没想到LocalizationSettings引申出这么多,我们还是要回到当初那个位置,从那里继续。回到WebWorkContext类的方法WorkingLanguage。

    Language detectedLanguage = null;
                    if (_localizationSettings.SeoFriendlyUrlsForLanguagesEnabled)
                    {
                        //get language from URL
                        detectedLanguage = GetLanguageFromUrl();
                    }

    从数据库得到的SeoFriendlyUrlsForLanguagesEnabled是False,所以继续往下。

    if (detectedLanguage == null && _localizationSettings.AutomaticallyDetectLanguage)

    AutomaticallyDetectLanguage数据库该值也是false.

    返回false的都不执行,我们接着往下:

    var allLanguages = _languageService.GetAllLanguages(storeId: _storeContext.CurrentStore.Id);

    这一句,从词义看就是返回所有语言。

    元旦过了,继续写咱的笔记。

    找到语言服务的实现类 amespace Nop.Services.Localization下的LanguageService : ILanguageService。方法如下:

    /// <summary>
            /// Gets all languages
            /// </summary>
            /// <param name="storeId">Load records allowed only in a specified store; pass 0 to load all records</param>
            /// <param name="showHidden">A value indicating whether to show hidden records</param>
            /// <returns>Language collection</returns>
            public virtual IList<Language> GetAllLanguages(bool showHidden = false, int storeId = 0)
            {
                string key = string.Format(LANGUAGES_ALL_KEY, showHidden);
                var languages = _cacheManager.Get(key, () =>
                {
                    var query = _languageRepository.Table;
                    if (!showHidden)
                        query = query.Where(l => l.Published);
                    query = query.OrderBy(l => l.DisplayOrder);
                    return query.ToList();
                });
    
                //store mapping
                if (storeId > 0)
                {
                    languages = languages
                        .Where(l => _storeMappingService.Authorize(l, storeId))
                        .ToList();
                }
                return languages;
            }

    个人现在觉得 ,好像storeId 是用来管理多点的吧,或者多个存储库。

    第一句  格式化KEY。

    第二句 通过KEY,从缓存获得这个表达式的值,缓存60分钟.

    表达式函数你用到的存储库声明如下:

    private readonly IRepository<Language> _languageRepository;

    可见  查的数据库表是Language表,获得所有已发布的,最后根据DisplayOrder排序。返回语言列表。

    执行 下一句:

    //find current customer language
                    var languageId = this.CurrentCustomer.GetAttribute<int>(SystemCustomerAttributeNames.LanguageId,

    currentCustomer代码如下:

    /// <summary>
            /// Gets or sets the current customer
            /// </summary>
            public virtual Customer CurrentCustomer
            {
                get
                {
                    if (_cachedCustomer != null)
                        return _cachedCustomer;
    
                    Customer customer = null;
                    if (_httpContext == null || _httpContext is FakeHttpContext)
                    {
                        //check whether request is made by a background task
                        //in this case return built-in customer record for background task
                        customer = _customerService.GetCustomerBySystemName(SystemCustomerNames.BackgroundTask);
                    }
    
                    //check whether request is made by a search engine
                    //in this case return built-in customer record for search engines 
                    //or comment the following two lines of code in order to disable this functionality
                    if (customer == null || customer.Deleted || !customer.Active)
                    {
                        if (_userAgentHelper.IsSearchEngine())
                            customer = _customerService.GetCustomerBySystemName(SystemCustomerNames.SearchEngine);
                    }
    
                    //registered user
                    if (customer == null || customer.Deleted || !customer.Active)
                    {
                        customer = _authenticationService.GetAuthenticatedCustomer();
                    }
    
                    //impersonate user if required (currently used for 'phone order' support)
                    if (customer != null && !customer.Deleted && customer.Active)
                    {
                        var impersonatedCustomerId = customer.GetAttribute<int?>(SystemCustomerAttributeNames.ImpersonatedCustomerId);
                        if (impersonatedCustomerId.HasValue && impersonatedCustomerId.Value > 0)
                        {
                            var impersonatedCustomer = _customerService.GetCustomerById(impersonatedCustomerId.Value);
                            if (impersonatedCustomer != null && !impersonatedCustomer.Deleted && impersonatedCustomer.Active)
                            {
                                //set impersonated customer
                                _originalCustomerIfImpersonated = customer;
                                customer = impersonatedCustomer;
                            }
                        }
                    }
    
                    //load guest customer
                    if (customer == null || customer.Deleted || !customer.Active)
                    {
                        var customerCookie = GetCustomerCookie();
                        if (customerCookie != null && !String.IsNullOrEmpty(customerCookie.Value))
                        {
                            Guid customerGuid;
                            if (Guid.TryParse(customerCookie.Value, out customerGuid))
                            {
                                var customerByCookie = _customerService.GetCustomerByGuid(customerGuid);
                                if (customerByCookie != null &&
                                    //this customer (from cookie) should not be registered
                                    !customerByCookie.IsRegistered())
                                    customer = customerByCookie;
                            }
                        }
                    }
    
                    //create guest if not exists
                    if (customer == null || customer.Deleted || !customer.Active)
                    {
                        customer = _customerService.InsertGuestCustomer();
                    }
    
    
                    //validation
                    if (!customer.Deleted && customer.Active)
                    {
                        SetCustomerCookie(customer.CustomerGuid);
                        _cachedCustomer = customer;
                    }
    
                    return _cachedCustomer;
                }
                set
                {
                    SetCustomerCookie(value.CustomerGuid);
                    _cachedCustomer = value;
                }
            }

    我们先分析customer = _customerService.GetCustomerBySystemName(SystemCustomerNames.BackgroundTask); 这一句。

    public virtual Customer GetCustomerBySystemName(string systemName)
            {
                if (string.IsNullOrWhiteSpace(systemName))
                    return null;
    
                var query = from c in _customerRepository.Table
                            orderby c.Id
                            where c.SystemName == systemName
                            select c;
                var customer = query.FirstOrDefault();
                return customer;
            }

    就是从Customer表获得systemName相等的customer记录。systemName 是SystemCustomerNames.BackgroundTask,就是字符串BackgroundTask。

    然后研究Customer的GetAttribute方法,这是一个扩展方法:

    public static TPropType GetAttribute<TPropType>(this BaseEntity entity,
                string key, IGenericAttributeService genericAttributeService, int storeId = 0)
            {
                if (entity == null)
                    throw new ArgumentNullException("entity");
    
                string keyGroup = entity.GetUnproxiedEntityType().Name;
    
                var props = genericAttributeService.GetAttributesForEntity(entity.Id, keyGroup);
                //little hack here (only for unit testing). we should write ecpect-return rules in unit tests for such cases
                if (props == null)
                    return default(TPropType);
                props = props.Where(x => x.StoreId == storeId).ToList();
                if (props.Count == 0)
                    return default(TPropType);
    
                var prop = props.FirstOrDefault(ga =>
                    ga.Key.Equals(key, StringComparison.InvariantCultureIgnoreCase)); //should be culture invariant
    
                if (prop == null || string.IsNullOrEmpty(prop.Value))
                    return default(TPropType);
    
                return CommonHelper.To<TPropType>(prop.Value);
            }

    string keyGroup = entity.GetUnproxiedEntityType().Name;  获得这个类的类型名称。

    找到IGenericAttributeService的实现类GenericAttributeService。方法:

    /// <summary>
            /// Get attributes
            /// </summary>
            /// <param name="entityId">Entity identifier</param>
            /// <param name="keyGroup">Key group</param>
            /// <returns>Get attributes</returns>
            public virtual IList<GenericAttribute> GetAttributesForEntity(int entityId, string keyGroup)
            {
                string key = string.Format(GENERICATTRIBUTE_KEY, entityId, keyGroup);
                return _cacheManager.Get(key, () =>
                {
                    var query = from ga in _genericAttributeRepository.Table
                                where ga.EntityId == entityId &&
                                ga.KeyGroup == keyGroup
                                select ga;
                    var attributes = query.ToList();
                    return attributes;
                });
            }

    private readonly IRepository<GenericAttribute> _genericAttributeRepository; 是用的库的声明,数据就是从GenericAttribute表里根据EntityId 和KeyGroup 获得的。

    最后 var language = allLanguages.FirstOrDefault(x => x.Id == languageId); 获得语言记录。

  • 相关阅读:
    适配器模式
    快排变种
    美团面试问题
    gulp前端自动化构建工具新手入门篇
    javascript继承
    .call()和.apply()相同点与不同点
    JavaScript原型,原型链 !
    锚点链接和hash属性
    构造函数与普通函数的比较
    JS的作用域和作用域链
  • 原文地址:https://www.cnblogs.com/runit/p/4196093.html
Copyright © 2011-2022 走看看