基於NopCommerce的開發框架——緩存、網站設置、系統日誌、用戶操做日誌

  最近忙於學車,抽時間將Nop的一些公用模塊添加進來,反應的一些小問題也作了修復。前篇——基於nopCommerce的開發框架(附源碼)http://www.cnblogs.com/dreling/p/6906688.html
  最新的代碼已經同布到GitHub:https://github.com/dreling8/Nop.Framework,有興趣的能夠關注該項目,後續其它的一些通用模塊也會添加進去,如用戶、權限、本地化、任務、插件功能等。歡迎star給星星,你的支持是個人動力!

  1、緩存模塊

  nopCommerce項目緩存類層級圖
  

  

  ICacheManager接口,該接口定義了數據緩存經常使用的方法。 
  CacheExtensions擴展方法對ICacheManager進行擴展。
  MemoryCacheCache類,使用.net  緩存框架實現數據緩存。
  PerRequestCacheManager類,實現頁面請求級的數據緩存。
  RedisCacheManager類,實現Redis數據緩存類。
  NopNullCache類,空的數據緩存類實現。
  IRedisConnectionWrapper接口,redis鏈接封裝接口。
  RedisConnectionWrapper類,redis鏈接實現。
  
  緩存的使用 
  在依賴注入中(DependencyRegistrar),將緩存注入到IOC容器中,系統默認使用MemoryCacheCache,若是想使用redis緩存可在配置模塊啓用並設置相關參數。
  
     //cache managers
     if (config != null && config.RedisCachingEnabled)     {        builder.RegisterType<RedisConnectionWrapper>().As<IRedisConnectionWrapper>().SingleInstance();     builder.RegisterType<RedisCacheManager>().As<ICacheManager>().Named<ICacheManager>("nop_cache_static").InstancePerLifetimeScope();     }     else     {     builder.RegisterType<MemoryCacheManager>().As<ICacheManager>().Named<ICacheManager>("nop_cache_static").SingleInstance();     }     builder.RegisterType<PerRequestCacheManager>().As<ICacheManager>().Named<ICacheManager>("nop_cache_per_request").InstancePerLifetimeScope();
  在用戶操做服務UserActivityService中能夠了解到,數據緩存是如何處理的,在數據檢索時,直接從緩存取數據,其餘方法均根據相關正則表達式移除ActivityLogType的全部緩存,以免讀取到髒數據。
 
          protected virtual IList<ActivityLogTypeForCaching> GetAllActivityTypesCached() { //cache
                string key = string.Format(ACTIVITYTYPE_ALL_KEY); return _cacheManager.Get(key, () => { var result = new List<ActivityLogTypeForCaching>(); var activityLogTypes = GetAllActivityTypes(); foreach (var alt in activityLogTypes) { var altForCaching = new ActivityLogTypeForCaching { Id = alt.Id, SystemKeyword = alt.SystemKeyword, Name = alt.Name, Enabled = alt.Enabled }; result.Add(altForCaching); } return result; }); }

  

  2、設置模塊

  Nop的設置功能實現比較有意思,先看類層級圖。
  
  ILocalizedEntity接口,暫時忽略該接口。 
  ISettings接口,設置接口。 
  Setting類,設置實體類。
  CommonSettings類,一個實現ISettings接口的通用設置類。
  
  經過Autofac的IRegistrationSource接口,將全部的設置類注入。
     public class SettingsSource : IRegistrationSource { static readonly MethodInfo BuildMethod = typeof(SettingsSource).GetMethod( "BuildRegistration", BindingFlags.Static | BindingFlags.NonPublic); public IEnumerable<IComponentRegistration> RegistrationsFor( Service service, Func<Service, IEnumerable<IComponentRegistration>> registrations) { var ts = service as TypedService; if (ts != null && typeof(ISettings).IsAssignableFrom(ts.ServiceType)) { var buildMethod = BuildMethod.MakeGenericMethod(ts.ServiceType); yield return (IComponentRegistration)buildMethod.Invoke(null, null); } } static IComponentRegistration BuildRegistration<TSettings>() where TSettings : ISettings, new() { return RegistrationBuilder .ForDelegate((c, p) => { ////var currentStoreId = c.Resolve<IStoreContext>().CurrentStore.Id;
                    //uncomment the code below if you want load settings per store only when you have two stores installed. //var currentStoreId = c.Resolve<IStoreService>().GetAllStores().Count > 1 // c.Resolve<IStoreContext>().CurrentStore.Id : 0; //although it's better to connect to your database and execute the following SQL: //DELETE FROM [Setting] WHERE [StoreId] > 0
                    return c.Resolve<ISettingService>().LoadSetting<TSettings>(); }) .InstancePerLifetimeScope() .CreateRegistration(); } public bool IsAdapterForIndividualComponents { get { return false; } } }
  
  如何添加相關的設置
  像commonsetting同樣,只須要定義一個實現空接口ISettings的類,而後的數據表中添加相關的配置,數據庫中Name值對應:類名 + . + 屬性名,和接口注入方式同樣,不過這裏使用類注入。另外須要注意的是在Nop.Core項目ComponentModel目錄下的GenericDictionaryTypeConverter和GenericListTypeConverter類中重寫了泛型List和泛型Dictionary的CanConvertFrom和ConvertFrom方法,使得數據庫中存儲字符串能轉換成對應的List和Dictionary,如List存儲時咱們只須要將多個數據使用英文符號(,)分隔符便可。

    public class CommonSettings : ISettings { public CommonSettings() { IgnoreLogWordlist = new List<string>(); } /// <summary>
        /// Gets or sets a value indicating whether stored procedures are enabled (should be used if possible) /// </summary>
        public bool UseStoredProceduresIfSupported { get; set; } /// <summary>
        /// Gets or sets a value indicating whether to use stored procedure (if supported) for loading categories (it's much faster in admin area with a large number of categories than the LINQ implementation) /// </summary>
        public bool UseStoredProcedureForLoadingCategories { get; set; } /// <summary>
        /// Gets or sets a value indicating whether 404 errors (page or file not found) should be logged /// </summary>
        public bool Log404Errors { get; set; } /// <summary>
        /// Gets or sets ignore words (phrases) to be ignored when logging errors/messages /// </summary>
        public List<string> IgnoreLogWordlist { get; set; } }
View Code

 

    public class HomeController : Controller { public ILogger _logger; public IUserActivityService _userActivityService; public CommonSettings _commonSettings; public HomeController( ILogger logger, IUserActivityService userActivityService, CommonSettings commonSetting) { _logger = logger; _userActivityService = userActivityService; _commonSettings = commonSettings; } public ActionResult Index() { TestSettings(); TestLogger(); return View(); } private void TestSettings() { var s = _commonSettings.IgnoreLogWordlist; } private void TestLogger() { _logger.InsertLog(LogLevel.Information, "index visit"); _userActivityService.InsertActivity(ActivityLogTypeEnum.AddUser, "添加用戶{0},{1}", new string[2] { "aaaa", "bbb" }); } }
  
  數據庫配置(IDataProvider)
  以前使用web.config配置的connectionStrings,如今改成IDataProvider的實現來統一配置相關的參數,特別提示數據庫配置文件在App_Data目錄下的Settings.txt,若是沒有新建一個,系統運行後會根據EntityFramework的數據映射自動建立相關表。
DataProvider: sqlserver
DataConnectionString: Data Source=.;Initial Catalog=nopFramework;Integrated Security=False;Persist Security Info=False;User ID=sa;Password=sa1234

 

 3、日誌模塊

  ILogger接口,日誌接口。 
  NullLogger類,Logger接口空實現。
  DefaultLogger類,Nop默認的日誌接口實現。 
  LoggingExtensions類,日誌擴展,使用日誌的擴展方法來存儲不一樣級別的日誌記錄。
  IUserActivityService接口,用戶操做服務接口。
  UserActivityService類,用戶操做服務實現。
 
  Nop沒有使用相似於Log4net的開源日誌記錄組件,固然若是你想使用能夠經過實現接口來引入。 IUserActivityService用於記錄用戶操做的記錄,須要在ActivityLogType表配置好用戶操做的類型,這裏優化了一下,將類型經過枚舉列出來,這樣在記錄用戶操做的時候不至於輸錯參數。 在首頁的控制器中加入測試代碼,日誌和操做記錄都添加到了數據庫中。
     private void TestLogger() { _logger.InsertLog(LogLevel.Information, "index visit"); _userActivityService.InsertActivity(ActivityLogTypeEnum.AddUser, "添加用戶{0},{1}", new string[2] { "aaaa", "bbb" }); }
  
  至此,開發框架中添加了經常使用的緩存、網站設置、系統日誌、用戶操做日誌功能。
相關文章
相關標籤/搜索