Abp 扩展设置
在ABP 框架中,已经自带了设置管理。包括读取,存储和修改。
不过,设置管理 都是 以 设置名称(name) 来读取控制的。在一些情况下,我希望 将设置的一类值放在一起,以单独的一个类(实体) 来读取访问,来更好的控制。
比如:我需要保存网站用于发送邮件的SMTP信息。我不想使用这种默认的方法来读取,因为太麻烦了,并且有可能 会造成错误。
//读取 string host = await SettingManager.GetSettingValueForApplicationAsync("smtp_host"); string username = await SettingManager.GetSettingValueForApplicationAsync("smtp_username"); string password = await SettingManager.GetSettingValueForApplicationAsync("smtp_password"); string email = await SettingManager.GetSettingValueForApplicationAsync("smtp_userPassword"); int port = await SettingManager.GetSettingValueForApplicationAsync<int>("smtp_port"); bool ssl = await SettingManager.GetSettingValueForApplicationAsync<bool>("smtp_ssl"); // 保存 await SettingManager.ChangeSettingForApplicationAsync("smtp_host", "smtp.qq.com"); // ...
像这样,在抹些情况下,很容易出错。
然而,我希望将这一组信息独立到一个类里面(实体)。
/// <summary> /// SMTP 设置 /// </summary> public class SmtpSetting { /// <summary> /// 主机 /// </summary> public string Host { get; set; } /// <summary> /// Email /// </summary> public string Email { get; set; } /// <summary> /// 端口 /// </summary> public int Port { get; set; } /// <summary> /// 使用SSL /// </summary> public bool UseSsl { get; set; } /// <summary> /// 用户名 /// </summary> public string Username { get; set; } /// <summary> /// 密码 /// </summary> public string Password { get; set; } public bool IsEnable() { return !string.IsNullOrEmpty(Host) && !string.IsNullOrEmpty(Email) && !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password); } }
但是,我在 ABP 的 SettingManager 中并没有找到对应的方法(也许是我没找到),,,为此: 我扩展了 SettingManager 的方法,使 SettingManager 可以直接读取和修改 一个 类设置。
首先,定义一个类设置接口,其中并没有任何定义。
/// <summary>
/// 只是一个标记
/// </summary>
public interface IEntitySetting
{
}
第二步,扩展 SettingManager 的方法:
public static class SettingManagerExtensions { public static async Task<T> GetEntitySettingValueAsync<T>(this ISettingManager settingManager) where T : IEntitySetting, new() { var settings = Activator.CreateInstance<T>(); var propes = typeof(T).GetProperties().Where(t => t.CanRead && t.CanWrite); foreach (var p in propes) { var key = string.Format("{0}.{1}", typeof(T).Name, p.Name); string setting = await settingManager.GetSettingValueAsync(key); if (setting == null) continue; if (!TypeDescriptor.GetConverter(p.PropertyType).CanConvertFrom(typeof(string))) continue; if (!TypeDescriptor.GetConverter(p.PropertyType).IsValid(setting)) continue; object value = TypeDescriptor.GetConverter(p.PropertyType).ConvertFromInvariantString(setting); p.SetValue(settings, value); } return settings; } public static async Task ChangeEntitySettingForApplicationAsync<T>(this ISettingManager settingManager, T setting) where T : IEntitySetting { var propes = typeof(T).GetProperties().Where(t => t.CanRead && t.CanWrite); foreach (var p in propes) { var key = string.Format("{0}.{1}", typeof(T).Name, p.Name); if (!TypeDescriptor.GetConverter(p.PropertyType).CanConvertFrom(typeof(string))) continue; object value = p.GetValue(setting, null); if (value != null) await settingManager.ChangeSettingForApplicationAsync(key, value.ToString()); else await settingManager.ChangeSettingForApplicationAsync(key, ""); } } public static async Task ChangeEntitySettingForUserAsync<T>(this ISettingManager settingManager, T setting, long userId) where T : IEntitySetting { var propes = typeof(T).GetProperties().Where(t => t.CanRead && t.CanWrite); foreach (var p in propes) { var key = string.Format("{0}.{1}", typeof(T).Name, p.Name); if (!TypeDescriptor.GetConverter(p.PropertyType).CanConvertFrom(typeof(string))) continue; dynamic value = p.GetValue(setting, null); if (value != null) await settingManager.ChangeSettingForUserAsync(userId, key, (string)value); else await settingManager.ChangeSettingForUserAsync(userId, key, ""); } } public static async Task ChangeEntitySettingForTenantAsync<T>(this ISettingManager settingManager, T setting, int tenantId) where T : IEntitySetting { var propes = typeof(T).GetProperties().Where(t => t.CanRead && t.CanWrite); foreach (var p in propes) { var key = string.Format("{0}.{1}", typeof(T).Name, p.Name); if (!TypeDescriptor.GetConverter(p.PropertyType).CanConvertFrom(typeof(string))) continue; dynamic value = p.GetValue(setting, null); if (value != null) await settingManager.ChangeSettingForTenantAsync(tenantId, key, (string)value); else await settingManager.ChangeSettingForTenantAsync(tenantId, key, ""); } } }
第三步,添加 一个 SettingProvider ,因为, ABP 中的 setting 必须 要先定义 SettingDefinition ,才能使用。
public class EntitySettingProvider : SettingProvider
{
public override IEnumerable<SettingDefinition> GetSettingDefinitions(SettingDefinitionProviderContext context)
{
var types = Assembly.GetAssembly(typeof(IEntitySetting)).GetTypes().Where(t => typeof(IEntitySetting).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface);
var result = new List<SettingDefinition>();
foreach (var type in types)
{
var settings = Activator.CreateInstance(type);
var propes = type.GetProperties().Where(t => t.CanRead && t.CanWrite);
foreach (var p in propes)
{
string name = string.Format("{0}.{1}", type.Name, p.Name);
var setting = new SettingDefinition(name, "");
// 取初始值
if (TypeDescriptor.GetConverter(p.PropertyType).CanConvertFrom(typeof(string)))
{
object value = p.GetValue(settings, null);
if (value != null)
setting = new SettingDefinition(name, value.ToString());
}
result.Add(setting);
}
}
return result;
}
}
第四步,将 EntitySettingProvider 添加到 Configuration 中的 Settings 里面。
// Settings
Configuration.Settings.Providers.Add<EntitySettingProvider>();
OK , 好了!。
将一开始的 SmtpSetting 修改下。
/// <summary> /// SMTP 设置 /// </summary> public class SmtpSetting : IEntitySetting { // ... }
获取设置:
var settingEntity = await SettingManager.GetEntitySettingValueAsync<SmtpSetting>();
修改设置:
await SettingManager.ChangeEntitySettingForApplicationAsync(new SmtpSetting(){ Host = "smtp.qq.com" });
Categories:
.net
已禁用评论。