在系统我们自定一个 MySettingProvider,并添加到配置集合中,定义一些邮件参数覆盖默认参数,然后通过IOC容器得到SmtpEmailSender实例,调用send方法就实现了,实现代码如下:
1.自定义配置类
public class MySettingProvider : SettingProvider{ public override IEnumerableGetSettingDefinitions(SettingDefinitionProviderContext context) { return new[] { new SettingDefinition(EmailSettingNames.Smtp.Host, "smtp.qq.com"), new SettingDefinition(EmailSettingNames.Smtp.Port,"25"), new SettingDefinition(EmailSettingNames.DefaultFromAddress,"834663884@qq.com"), new SettingDefinition(EmailSettingNames.Smtp.UserName,"834663884@qq.com"), new SettingDefinition(EmailSettingNames.Smtp.Password,""), new SettingDefinition(EmailSettingNames.Smtp.UseDefaultCredentials,"false"), new SettingDefinition(EmailSettingNames.DefaultFromDisplayName,"shuangjie"), new SettingDefinition( AbpZeroSettingNames.UserManagement.IsEmailConfirmationRequiredForLogin, "true", new FixedLocalizableString("Is email confirmation required for login."), scopes: SettingScopes.Application | SettingScopes.Tenant ) }; } }
2.添加到配置集合,加到模块初始化类里就行
Configuration.Settings.Providers.Add();
3.使用SmtpEmailSender
var emailSender = IocManager.Instance.Resolve();emailSender.Send(message.Destination, message.Subject, message.Body);
4.下面将框架是如何实现这些操作的
在SmtpEmailSender的构造函数中注入了ISmtpEmailSenderConfiguration,它的实现类是SmtpEmailSenderConfiguration,通过他我们的Send方法得到我们需要的邮箱配置,那让我们看究竟做了什么
public class SmtpEmailSenderConfiguration : EmailSenderConfiguration, ISmtpEmailSenderConfiguration, ITransientDependency{ public string Host { get { return GetNotEmptySettingValue(EmailSettingNames.Smtp.Host); } } public int Port { get { return SettingManager.GetSettingValue (EmailSettingNames.Smtp.Port); } } ....
他通过SettingManager的GetSettingValue方法来得到一些配置的值,SettingManager字段,GetNotEmptySettingValue方法来自EmailSenderConfiguration,这里就不粘它的代码了,GetNotEmptySettingValue也是通过SettingManager.GetSettingValue的方式来获得配置数据的,GetSettingValue是SettingManager的扩展方法,接下来就让我看看SettingManager类
public class SettingManager : ISettingManager, ISingletonDependency{ public TaskGetSettingValueAsync(string name) { return GetSettingValueInternalAsync(name, AbpSession.TenantId, AbpSession.UserId); } private async Task GetSettingValueInternalAsync(string name, int? tenantId = null, long? userId = null) { var settingDefinition = _settingDefinitionManager.GetSettingDefinition(name); //Get for user if defined if (settingDefinition.Scopes.HasFlag(SettingScopes.User) && userId.HasValue) {
SettingScope是枚举,有三个值分别是Application、TenantId、UserId,在这里不讲,通过代码们看到获取配置的方法是_settingDefinitionManager的GetSettingDefinition,返回结果是SettingDefinition,这个类主要用来保存Name、Value等等属性,我们要看的是GetSettingDefinition方法,代码如下
internal class SettingDefinitionManager : ISettingDefinitionManager, ISingletonDependency{ public void Initialize() { var context = new SettingDefinitionProviderContext(); foreach (var providerType in _settingsConfiguration.Providers) { var provider = CreateProvider(providerType); foreach (var settings in provider.GetSettingDefinitions(context)) { _settings[settings.Name] = settings; } } } public SettingDefinition GetSettingDefinition(string name) { SettingDefinition settingDefinition; if (!_settings.TryGetValue(name, out settingDefinition)) { throw new AbpException("There is no setting defined with name: " + name); } return settingDefinition; }
通过代码我们看到SettingDefinition来自Provider,也就是我们自定义或默认已有的SettingProvider类,这个类有个方法GetSettingDefinitions,通过它来得到我们的配置,SettingDefinitionManager的Initialize会在程序启动时被调用,详看AbpKernelModule,这个初始化方法就得到了所有的SettingDefinition,这就是大概流程,因为在AbpKernelModule添加的的SettingProvider会早于我们自定义的SettingProvider,所以我们的会覆盖默认的。
到此结束!