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. Ocelot API网关的实现剖析

    在微软Tech Summit 2017 大会上和大家分享了一门课程<.NET Core 在腾讯财付通的企业级应用开发实践>,其中重点是基于ASP.NET Core打造可扩展的高性能企业级A ...

  2. Xcode修改个性化注释

    1.首先找到Xcode进入包内容 2.依次进入/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Develo ...

  3. MYSQL触发器在PHP项目中用来做信息备份、恢复和清空

    案例:通过PHP后台代码可以将员工的信息删除,将删除的员工信息进行恢复(类似于从回收站中恢复员工信息),并且还可以将已经删除的员工进行清空(类似于清空回复站的功能). 思路:要有一张员工表,还要有一张 ...

  4. oracle数据库表实现主键自增功能

    有关oracle中自增序列sequence+触发器trigger:实现数据表TABDATA_LIVE_CYCLE中的主键id的自增. CREATE SEQUENCE TABDATA_LIVE_CYCL ...

  5. 微信分享 JSSDK的使用

    我现在做过的在微信中运行的项目,基本上都有微信分享功能,所以,会使用JSSDK分享页面是非常重要的.分享功能的代码一般会放在beforeCreate或mounted钩子中,代码如下: this.$ht ...

  6. [转载] redis 的两种持久化方式及原理

    转载自http://www.m690.com/archives/371 Redis是一种高级key-value数据库.它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富.有字符串 ...

  7. 一致性hash算法以及其在分布式系统中的应用(转)

    初始架构

  8. MySQL执行一个查询的过程

    总体流程 客户端发送一条查询给服务器: 服务器先会检查查询缓存,如果命中了缓存,则立即返回存储在缓存中的结果.否则进入下一阶段: 服务器端进行SQL解析.预处理,再由优化器生成对应的执行计划: MyS ...

  9. 翻译连载 | 附录 A:Transducing(上)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...

  10. ligerUI---下拉菜单(menubar)动态显示(从后台获取数据)

    写在前面: ligerui的下拉菜单是有点丑的,这也是没有办法的事........这里主要记录下,如何从后台获取数据进行菜单显示. 有两种方式:1.使用json数组来动态添加  2.字符串拼接.  其 ...