本系列目录
Asp.Net DDD架构浅谈——整体框架说明
Asp.Net DDD架构浅谈——领域划分、仓储应用、Services层定义
Asp.Net DDD架构浅谈——图片上传、缩略裁剪
Asp.Net DDD架构浅谈——依赖注入Autofac
Asp.Net DDD架构浅谈——网站配置
这里的网站配置不是指项目中的Web.config, 在开发网站的时候,我们常常用到一些可能会变动的配置类项,比如说网站名称、CopyRight、统计脚本等等内容。
最简单的做法是在代码中写死,但是不灵活,比如说CopyRight从2017——》2018时,难道我们每个项目修改一遍,然后重新编译上传代码码?显然不行。
那合适的做法是什么呢?用一个配置的类来管理这些灵活变动的值,通过后台配置即可。
XML配置
在最开始做项目的时候,是通过一个XML的配置文件来记录这些配置值,如下代码:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--网站信息-->
<add key="website_name" desc="网站名称">网站名称</add>
<add key="website_url" desc="网站地址">http://localhost:2017</add>
<add key="website_copyright" desc="网站版权信息">Copyright©localhost 2018 ICP备xxxxx号-1</add>
</configuration>
然后通过一个类来管理这个XML配置,读取xml中的key、value数据,存储到缓存中,当需要修改值时,直接打开xml文件修改对应的地方,或者新增、删除。
缺点
- 更新麻烦!至今任然记得每次更新网站,都需要打开两个xml文件,一个是正式环境的,一个是测试的,挨个比对,去修改,眼睛那个疼😭!
- 跨网站不好管理,当业务需要整个项目拆分为几个二级域名时,这几个网站共用一个xml是很麻烦的。
表配置
通过思考,对遇到的问题的总结,把存储从xml转移到表中,而配置(增删改查)直接通过后台来处理。这样就实现了简单配置的目的。下面来看看如何实现的。
首先是表定义:
/// <summary>
/// 配置表
/// </summary>
[Table("SysConfig")]
public class SysConfig : AggregateRoot
{
/// <summary>
/// 配置Key
/// </summary>
public string ConKey { get; set; }
/// <summary>
/// 配置值,Json格式
/// </summary>
public string ConValue { get; set; }
/// <summary>
/// 配置名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 值类型,int、long等
/// </summary>
public SysConfigType ConfigType { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
/// <summary>
/// 配置分类:网站配置、上传配置等
/// </summary>
public SysConfigClassify ConfigClassify { get; set; }
}
注意,我们用ConValue来存储每个配置的值,但是配置值有很多种类型,因此这里用Json格式来存储。
然后是看下SysConfigRepository仓储:
/// <summary>
/// 网站名称
/// </summary>
public string WebSiteName
{
get
{
return GetConfig<string>(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// 网站CopyRight
/// </summary>
public string WebSiteCopyRight
{
get
{
return GetConfig<string>(MethodBase.GetCurrentMethod());
}
}
public string WebSiteICP
{
get
{
return GetConfig<string>(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// 上传文件限制
/// </summary>
public string[] UploadFileTypes
{
get
{
return GetConfig<string[]>(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// 上传文件大小限制
/// </summary>
public int UploadFileSizes
{
get
{
return GetConfig<int>(MethodBase.GetCurrentMethod());
}
}
我们只要定义属性即可,都是调用GetConfig函数来获取,来看下GetConfig函数:
private T GetConfig<T>(MethodBase method)
{
try
{
var configKey = method.Name;
if (configKey.StartsWith("get_"))
{
configKey = configKey.Substring(4).Trim();
}
else
{
throw new Exception("GetConfig 方法只能在get属性中调用!");
}
var cacheKey = string.Format(ConfigPatternByKey, configKey);
var result = Cache.Get<T>(cacheKey, CacheKey, () =>
{
var config = GetByKey(configKey);
if (config == null)
{
var typeName = typeof(T).Name;
config = CreateDefaultConfig(typeName, configKey);
Save(config);
}
T cacheResult;
if (string.IsNullOrEmpty(config.ConValue))
{
cacheResult = default(T);
}
else
{
cacheResult = JsonConvert.DeserializeObject<T>(config.ConValue);
}
return cacheResult;
});
return result;
}
catch (Exception ex)
{
Log.Error(ex);
return default(T);
}
}
这里做了一些逻辑处理,首先获取属性的名称,比如说WebSiteName,做为ConKey去缓存中去取对应的值,不存在则在数据库中查询,还是不存在,则插入这条数据,这样后台就可以看到新增的这条配置了。
而调用的时候非常简单,直接通过ISysConfigRepository的属性调用即可。