Abp的扩展功能非常强大,配合持久化可以很方便的配置系统、租户、用户的配置,关于ABP的配置请参考:

http://www.cnblogs.com/farb/p/ABPSettingManagement.html

虽然此方式配合静态KEY配置使用ISettingManager获取很方便,但是还是有很多不便,每个配置都需要去单独获取并指定类型

并且一次只能获取一个配置值,那么我们能不能直接就像使用ISettingManager来直接注入我们的配置呢,今天的扩展将实现此

功能以达到如下需求:

配置:

     [AbpAuthorize]
public class ConfigurationAppService : XAppServiceBase, IConfigurationAppService
{
public XSettings GetXSettings()
{
var obj = IocManager.Instance.Resolve<XSettings>();
return obj;
} public async Task SaveXSettings(XSettings setting)
{
await setting.SaveAsync();
}
}

使用:

 public class DemoAppService : ApplicationService, IDemoAppService
{
public XSettings Settings { get; set; } public void Test()
{
var size = this.Settings.PageSize;
}
}

上面代码的重点在XSettings这个类上,那么就从这个类说起,先看看这个配置类:

    public class XSettings : SettingBase
{
[SettingDefinition("XProject")]
[Required(ErrorMessage = "系统名称不能为空!")]
public string SystemName { get; set; } [SettingDefinition(, true)]
public int PageSize { get; set; } //[SettingDefinition(true)]
public bool IsOpen { get; set; }
}

很简单的一个配置,但是有一个基类和一个特性,先看一下特性类

    public class SettingDefinitionAttribute : Attribute
{
public string DefaultValue { get; private set; } public bool IsVisibleToClients { get; private set; } public SettingScopes Scopes { get; private set; } public SettingDefinitionAttribute(object defaultValue, bool isVisibleToClients = true, SettingScopes scopes = SettingScopes.Application)
{
this.DefaultValue = defaultValue?.ToString();
this.IsVisibleToClients = isVisibleToClients;
this.Scopes = scopes;
}
}

我们的特性定义了该配置项的ABP配置功能,包括了默认值、是否显示到客户端、和使用域,这样就表示了配置类中的属性相关的ABP配置了

定义好了配置后,那我们怎么保存和获取呢?这就需要我们的基类出场了:

    public abstract class SettingBase : ITransientDependency
{
private ISettingManager _SettingManager;
private IAbpSession _Session; public SettingBase()
{
this._SettingManager = IocManager.Instance.Resolve<ISettingManager>();
this._Session = IocManager.Instance.Resolve<IAbpSession>();
var t = this.GetType();
var ps = t.GetProperties();
foreach (var p in ps)
{
var settingValue = _SettingManager.GetSettingValue($"{t.Name}.{p.Name}");
p.SetValue(this, Convert.ChangeType(settingValue, p.PropertyType));
}
} public async Task SaveAsync()
{
var t = this.GetType();
var ps = t.GetProperties();
foreach (var p in ps)
{
var key = $"{t.Name}.{p.Name}";
var val = p.GetValue(this)?.ToString();
var attr = p.GetCustomAttribute<SettingDefinitionAttribute>(); if (attr != null)
{ if (attr.Scopes.HasFlag(SettingScopes.User) && this._Session.UserId.HasValue)
await _SettingManager.ChangeSettingForUserAsync(this._Session.ToUserIdentifier(), key, val);
else if (attr.Scopes.HasFlag(SettingScopes.Tenant) && this._Session.TenantId.HasValue)
await _SettingManager.ChangeSettingForTenantAsync(this._Session.TenantId.Value, key, val);
else
await _SettingManager.ChangeSettingForApplicationAsync(key, val);
}
else
await _SettingManager.ChangeSettingForApplicationAsync(key, val);
}
} public void Save()
{
AsyncHelper.RunSync(() => { return this.SaveAsync(); });
} }

基类中也很简单,就是初始化的时候,从ISettingManager中加载相应的配置设置到对应的属性上,并定义了两个保存方法来保存我们修改后的配置

这里我之前用过一种方式就是直接设置属性的时候就自动保存,不过后面又换成了现在需要调用一个save方法的方式了。

定义好配置加载和保存了,就只剩下初始化了,我们希望我定义好配置类以后就能在启动的时候自动初始化,所以定义了一个AutoSettingProvider

    public class AutoSettingProvider : SettingProvider
{
public override IEnumerable<SettingDefinition> GetSettingDefinitions(SettingDefinitionProviderContext context)
{
var settings = new List<SettingDefinition>(); var types = this.GetType().Assembly
.GetTypes()
.Where(t => t.IsClass && typeof(SettingBase).IsAssignableFrom(t));
foreach (var t in types)
{
var scopes = SettingScopes.All;
foreach (var p in t.GetProperties())
{
var key = $"{t.Name}.{p.Name}";
var isVisibleToClients = false;
var defaultValue = p.PropertyType.IsValueType ? Activator.CreateInstance(p.PropertyType).ToString() : string.Empty;
var attr = p.GetCustomAttribute<SettingDefinitionAttribute>();
if (attr != null)
{
scopes = attr.Scopes;
defaultValue = attr.DefaultValue;
isVisibleToClients = attr.IsVisibleToClients;
}
settings.Add(new SettingDefinition(
name: key,
defaultValue: defaultValue,
scopes: scopes,
isVisibleToClients: isVisibleToClients
));
}
} return settings;
}
}

到这里,我们的配置扩展就算完成了。在所有我们需要使用的地方都可以直接注入使用了。

Abp扩展之【配置功能】的更多相关文章

  1. Spring Boot2.0+中,自定义配置类扩展springMVC的功能

    在spring boot1.0+,我们可以使用WebMvcConfigurerAdapter来扩展springMVC的功能,其中自定义的拦截器并不会拦截静态资源(js.css等). @Configur ...

  2. 使用C++扩展Python的功能 转自:http://blog.csdn.net/magictong/article/details/8897568#comments

    使用C++扩展Python的功能 环境 VS2005Python2.5.4 Windows7(32位) 简介 长话短说,这里说的扩展Python功能与直接用其它语言写一个动态链接库,然后让Python ...

  3. kindeditor扩展粘贴图片功能&修改图片上传路径并通过webapi上传图片到图片服务器

    前言 kindeditor是一个非常好用的富文本编辑器,它的简单使用我就不再介绍了. 而kindeditor却对图片的处理不够理想. 本篇博文需要解决的问题有两个: kindeditor扩展粘贴图片功 ...

  4. kindeditor扩展粘贴截图功能&修改图片上传路径并通过webapi上传图片到图片服务器

    前言 kindeditor是一个非常好用的富文本编辑器,它的简单使用我就不再介绍了. 而kindeditor却对图片的处理不够理想. 本篇博文需要解决的问题有两个: kindeditor扩展粘贴图片功 ...

  5. WCF学习之旅—WCF4.0中的简化配置功能(十五)

    六 WCF4.0中的简化配置功能 WCF4.0为了简化服务配置,提供了默认的终结点.绑定和服务行为.也就是说,在开发WCF服务程序的时候,即使我们不提供显示的 服务终结点,WCF框架也能为我们的服务提 ...

  6. Rest Client(Rest接口调试工具,有保存功配置功能) chrome浏览器插件

    Rest Client(Rest接口调试工具,有保存功配置功能) chrome浏览器插件 下载地址 插件的操作很简单,下面是一些简单的实例. 1.安装 在谷歌应用商城搜索postman,如下图1-1所 ...

  7. Postman 是一个非常棒的Chrome扩展,提供功能强大的API & HTTP 请求调试

    Postman 是一个非常棒的Chrome扩展,提供功能强大的API & HTTP 请求调试   需要FQ才能安装,使用时应该不用FQ了,除非使用postman的历史记录功能:   非常棒的C ...

  8. qmake的配置功能(Configuration Features)

    Configuration Features qmake can be set up with extra configuration features that are specified in f ...

  9. windows下安装MongoDB扩展和配置

    windows下安装MongoDB扩展和配置 1.下载mongoDB扩展,根据当前php版本进行下载 地址如下:http://pecl.php.net/package/mongo 我本地php版本是 ...

随机推荐

  1. dp百题大过关(第一场)

    好吧,这名字真是让我想起了某段被某教科书支配的历史.....各种DP题层出不穷,不过终于做完了orz 虽然各种手糊加乱搞,但还是要总结一下. T1 Monkey Banana Problem    这 ...

  2. HDU6127Hard challenge

    Hard challenge Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others) ...

  3. linux dig 命令

    dig 命令主要用来从 DNS 域名服务器查询主机地址信息. 查询单个域名的 DNS 信息 dig 命令最典型的用法就是查询单个主机的信息. $ dig baidu.com dig 命令默认的输出信息 ...

  4. centos 下安装jdk、tomcat 以及tomcat无法从外部访问的解决办法

    centos 下安装jdk.tomcat 以及tomcat无法从外部访问的解决办法 原创 2014年08月28日 10:24:33 标签: selinux enforce cent 2223 昨天在c ...

  5. CI脚本异常退出问题定位

    背景 在CI脚本中,使用类似如下脚本进行项目编译的计时,但在执行过程中,有时会出现CI脚本(命名为ci.sh)未完全执行的情况: #!/bin/bash -e sleep_time=$1 start_ ...

  6. ECMAScript 6 proxies

    在ECMAScript 5里面,可以通过(writable 和 configurable)内部属性把属性设置为不可修改和不可删除的,可以通过(Object.preventExtensions() )让 ...

  7. MySQL数据库中文变问号

    原文参考:http://www.linuxidc.com/Linux/2017-05/144068.htm 系统是的Ubuntu  16,修改以下配置 1.sudo vi /etc/mysql/my. ...

  8. 二叉搜索树的第 k 个结点

    题目 给定一颗二叉搜索树,请找出其中的第k小的结点,即将二叉树中所有元素从小到大排序的第 k 个结点. 解析 按中序遍历二叉搜索树就可以获得一个非递减的序列,此时第 k 个就为答案.实际上我们只需要按 ...

  9. JavaScript核心参考

    Array 方法 concat() 把元素衔接到数组中. every() 测试断言函数是否对每个数组元素都为真. filter() 返回满足断言函数的数组元素. forEach() 为数组的每一个元素 ...

  10. ImageAnimator类方法(动画设计)

    ImageAnimator类常用方法如表所示. 表    ImageAnimator类常用方法 方法 说明 Animate 将多帧图像显示为动画 CanAnimate 返回一个布尔值,该值指示指定图像 ...