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. Buy the Ticket(卡特兰数+递推高精度)

    Buy the Ticket Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...

  2. How Many Answers Are Wrong

    How Many Answers Are Wrong Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...

  3. JavaScript 语言精粹读书笔记

    最近在看 赵泽欣 / 鄢学鹍 翻译的 蝴蝶书, 把一些读后感言记录在这里. 主要是把作者的建议跟 ES5/ES5.1/ES6 新添加的功能进行了对比 涉及到的一些定义 IIFE: Immediatel ...

  4. js input输入事件兼容性问题

    if(navigator.userAgent.indexOf('Android') > -1){ $("#sign").on("input", funct ...

  5. CentOS7安装配置vncserver

    系统环境:CentOS Linux release 7.4.1708 Kernel:3.10.0-693.el7.x86_64 系统现状:最小化安装,没有安装任何图形支持软件 安装图形化支持 不建议安 ...

  6. JS5模拟类

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. jQuery_DOM学习之------遍历节点

    一.children()方法 例子: <!DOCTYPE html> <html> <head> <meta http-equiv="Content ...

  8. JavaScript系列----一切皆是对象

    1.判断对象类型 1.1.typeof 运算符 首先要认识到,typepof是一个运算符,其运算需要一个参数,返回值是参数的类型. typeof使用方法 typeof parameter //使用方法 ...

  9. SharePoint Online 创建用户和组

    前言 本文介绍如何在Office 365中创建用户和组,这里所说的用户和组,是指Office 365中的用户和组,我们可以用这里的用户登录Office 365环境,用组的概念来管理用户,而非Share ...

  10. Java IO(1)基础知识——字节与字符

    正所谓怕什么来什么,这是知名的“墨菲定律”.Java基础涵盖各个方面,敢说Java基础扎实的人不是刚毕业的学生,就是工作N年的程序员.工作N年的程序员甚至也不敢人人都说Java基础扎实,甚至精通,往往 ...