[Abp 源码分析]五、系统设置

Abp 本身有两种设置,一种就是 上一篇文章 所介绍的模块配置 Configuration,该配置主要用于一些复杂的数据类型设置,不仅仅是字符串,也有可能是一些 C# 运行时的一些变量。另外一种则是本篇文章所讲的 Setting,Setting 主要用于配置一些简单的参数,比如 SMTP 地址,数据库连接字符串等一些基本的配置类型可以使用 Setting 来进行处理。

1.代码分析 1.1 启动流程

我们先来看一下设置是怎样被加入到 Abp 框架当中,并且是如何来使用它的。

在 Abp 框架内部开发人员可以通过 ISettingsConfiguration 的 Providers 属性来添加自己实现的 SettingProvider ,而 ISettingsConfiguration 的初始化是在上一篇文章所写的 AbpBootstrapper.Initialize() 里面进行初始化的。

开发人员通过继承 SettingProvider 来提供这些设置信息,并且在模块的 PreInitialize() 方法当中通过 Configuration 来添加书写好的配置提供者。

在模块进行初始化之后(也就是在 PostInitiailze() 方法内部),所有开发人员定义的 SettingProvider 通过 ISettingDefinitionManager 的 Initialize() 方法存储到一个 Dictionary 里面。

public sealed class AbpKernelModule : AbpModule { // 其他代码 public override void PostInitialize() { // 其他代码 IocManager.Resolve<SettingDefinitionManager>().Initialize(); // 其他代码 } }

Initialize() 方法内部:

private readonly IDictionary<string, SettingDefinition> _settings; public void Initialize() { var context = new SettingDefinitionProviderContext(this); foreach (var providerType in _settingsConfiguration.Providers) { using (var provider = CreateProvider(providerType)) { foreach (var settings in provider.Object.GetSettingDefinitions(context)) { _settings[settings.Name] = settings; } } } }

对外则是通过 ISettingManager 来进行管理的。

所有的设置项是通过 ServiceProvider 来提供的。

设置的持久化配置则是通过 ISettingStore 来实现的,开发者可以通过替换 ISettingStore 的实现达到持久化到数据库或者是其他位置。

1.1.1 设置提供者定义 internal class EmailSettingProvider : SettingProvider { public override IEnumerable<SettingDefinition> GetSettingDefinitions(SettingDefinitionProviderContext context) { return new[] { new SettingDefinition(EmailSettingNames.Smtp.Host, "127.0.0.1", L("SmtpHost"), scopes: SettingScopes.Application | SettingScopes.Tenant), new SettingDefinition(EmailSettingNames.Smtp.Port, "25", L("SmtpPort"), scopes: SettingScopes.Application | SettingScopes.Tenant), new SettingDefinition(EmailSettingNames.Smtp.UserName, "", L("Username"), scopes: SettingScopes.Application | SettingScopes.Tenant), new SettingDefinition(EmailSettingNames.Smtp.Password, "", L("Password"), scopes: SettingScopes.Application | SettingScopes.Tenant), new SettingDefinition(EmailSettingNames.Smtp.Domain, "", L("DomainName"), scopes: SettingScopes.Application | SettingScopes.Tenant), new SettingDefinition(EmailSettingNames.Smtp.EnableSsl, "false", L("UseSSL"), scopes: SettingScopes.Application | SettingScopes.Tenant), new SettingDefinition(EmailSettingNames.Smtp.UseDefaultCredentials, "true", L("UseDefaultCredentials"), scopes: SettingScopes.Application | SettingScopes.Tenant), new SettingDefinition(EmailSettingNames.DefaultFromAddress, "", L("DefaultFromSenderEmailAddress"), scopes: SettingScopes.Application | SettingScopes.Tenant), new SettingDefinition(EmailSettingNames.DefaultFromDisplayName, "", L("DefaultFromSenderDisplayName"), scopes: SettingScopes.Application | SettingScopes.Tenant) }; } private static LocalizableString L(string name) { return new LocalizableString(name, AbpConsts.LocalizationSourceName); } } 1.1.2 注入设置提供者 public sealed class AbpKernelModule : AbpModule { public override void PreInitialize() { // 其他代码 Configuration.Settings.Providers.Add<EmailSettingProvider>(); // 其他代码 } }

注入之后,那么相应的模块如何得到已经注入的配置项呢?

我们拿一个最直观的例子来展示一下,这里我们来到 Abp 项目的 Email 模块,来看看它是如何使用的。

public class DefaultMailKitSmtpBuilder : IMailKitSmtpBuilder, ITransientDependency { private readonly ISmtpEmailSenderConfiguration _smtpEmailSenderConfiguration; public DefaultMailKitSmtpBuilder(ISmtpEmailSenderConfiguration smtpEmailSenderConfiguration) { _smtpEmailSenderConfiguration = smtpEmailSenderConfiguration; } public virtual SmtpClient Build() { var client = new SmtpClient(); try { ConfigureClient(client); return client; } catch { client.Dispose(); throw; } } protected virtual void ConfigureClient(SmtpClient client) { client.Connect( _smtpEmailSenderConfiguration.Host, _smtpEmailSenderConfiguration.Port, _smtpEmailSenderConfiguration.EnableSsl ); if (_smtpEmailSenderConfiguration.UseDefaultCredentials) { return; } client.Authenticate( _smtpEmailSenderConfiguration.UserName, _smtpEmailSenderConfiguration.Password ); } }

可以看到以上代码通过 ISmtpEmailSenderConfiguration 来拿到 SMTP 对应的主机名与端口号,那这与我们的 ISettingManager 又有何关系呢?

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wssfxp.html