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. C++ 随机生成一个(0,1)之间的小数

    double p; ]; memset(s,,sizeof(s)); s[]='; s[]='.'; ;i<;i++) { s[i]=rand()%+'; } p=atof(s); cout & ...

  2. 0_Simple__cppOverload

    使用cuda内质结构 cudaFuncAttributes 来观察核函数的共享内存.寄存器数量. ▶ 源代码: /*cppOverload_kernel.cuh*/ __global__ void s ...

  3. 记录我发现的第一个关于 Google 的 Bug

    先贴上 Bug 链接: https://issuetracker.google.com/issues/68969655 Bug 本身是很简单的,就是 Google 的 Android 在线参考文档中, ...

  4. FTP配置的一些笔记

    1.必须关闭防火墙 iptables -F iptables -X iptables -Z vi /etc/selinux/config          SELINUX=disabled seten ...

  5. Pycharm,Python原生IDE?

    老套路,安装和使用(Win7x64.JDK神马滴早已装好). 1.安装 网上下下来后就这东西 Next D盘路径 我选择.我喜欢 开装 好慢,以后用光纤 O了 桌面小图标 2.使用 以管理员身份打开软 ...

  6. JS模块化开发----require.js

    前言 前端开发中,起初只要在script标签中嵌入几十上百行代码就能实现一些基本的交互效果,后来js得到重视,应用也广泛起来了,jQuery,Ajax,Node.Js,MVC,MVVM等的助力也使得前 ...

  7. '@P0'附近有语法错误

    做一个分页查询功能,使用到了TOP #{pagenum}然后就报错了.'@P0'附近有语法错误 未解决:#{pagenum}改成${pagenum},但是mybatis报参数未找到错误, 解决:将对应 ...

  8. 如何在C#中使用存储过程(SQL Server 2000)

    要在C#中使用存储过程,首先看看test表的创建sql语句:   create table test55 ( uid int identity(1,1), class1 varchar(20), cl ...

  9. C#中抽象类和接口的区别3

    一.普通类和抽象类之间的异同 1.都可以被继承 2.抽象类不能被实例化,只是用来继承的.普通类可以实例化 3.抽象方法只有含方法声明而没有方法体且必须包含在抽象类里面 4.子类继承抽象类必须实现抽象类 ...

  10. 通过Xshell连接CentOS虚拟机

    1.通过"setup"配置网络ip(CentOS7不支持setup配置) 2.通过"service network restart"来重启网络服务 3.&quo ...