基于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" }); }
  
  至此,开发框架中添加了经常使用的缓存、网站设置、系统日志、用户操做日志功能。
相关文章
相关标签/搜索