C# IRealTimeNotifier中的租户会话丢失

C# IRealTimeNotifier中的租户会话丢失,c#,session,notifications,aspnetboilerplate,C#,Session,Notifications,Aspnetboilerplate,我们正在尝试实现一个场景,用户可以通过通道订阅通知 例如,用户可以通过电子邮件、短信、实时通知等订阅通知 目前,为了实现电子邮件通知,我正在通过以下方式实现iRelationMeNotifier: public class EmailNotifier : IRealTimeNotifier, ITransientDependency { private readonly IEmailSender _emailSender; private readonly ISettingMan

我们正在尝试实现一个场景,用户可以通过通道订阅通知

例如,用户可以通过电子邮件、短信、实时通知等订阅通知

目前,为了实现电子邮件通知,我正在通过以下方式实现
iRelationMeNotifier

public class EmailNotifier : IRealTimeNotifier, ITransientDependency
{
    private readonly IEmailSender _emailSender;
    private readonly ISettingManager _settingManager;

    public IAbpSession AbpSession { get; set; }

    public EmailNotifier(IEmailSender emailSender, ISettingManager settingManager, IAbpSession abpSession)
    {
        this._emailSender = emailSender;
        this._settingManager = settingManager;
        this.AbpSession = NullAbpSession.Instance;
    }

    public async Task SendNotificationsAsync(UserNotification[] userNotifications)
    {
        List<Task> sendEmails = new List<Task>();
        string fromAddress = this._settingManager.GetSettingValueForTenant(EmailSettingNames.Smtp.UserName, Convert.ToInt32(this.AbpSession.TenantId));

        foreach (UserNotification notification in userNotifications)
        {
            notification.Notification.Data.Properties.TryGetValue("toAddresses", out object toAddresses);
            notification.Notification.Data.Properties.TryGetValue("subject", out object sub);
            notification.Notification.Data.Properties.TryGetValue("body", out object content);
            notification.Notification.Data.Properties.TryGetValue("toAddresses", out object toAddresses);

            List<string> toEmails = toAddresses as List<string>                    ;
            string subject = Convert.ToString(sub);
            string body = Convert.ToString(content);
            toEmails.ForEach(to =>
            {
                sendEmails.Add(this._emailSender.SendAsync(fromAddress, to, subject, body));
            });
        }

        await Task.Run(() =>
        {
            sendEmails.ForEach(async task =>
            {
                try
                {
                    await task.ConfigureAwait(false);
                }
                catch (Exception)
                {
                    // TODO #1: Add email to background job to be sent later.
                    // TODO #2: Add circuit breaker to email sending mechanism
                    /*
                        Email sending is failing because of two possible reasons.
                        1. Email addresses are wrong.
                        2. SMTP server is down.
                        3. Break the circuit while the SMTP server is down.
                     */

                    // TODO #3 (Optional): Notify tenant admin about failure.
                    // TODO #4: Remove throw statement for graceful degradation.
                    throw;
                }
            });
        });
    }
}
有人能推荐一个更好的方法吗?或者指出我们在这里做错了什么

我还没有考虑如何处理这些特定通知程序的DI。出于测试目的,我在模块中给出了如下命名注入:

IocManager.IocContainer.Register(
    Component.For<IRealTimeNotifier>()
        .ImplementedBy<EmailNotifier>()
        .Named("Email")
        .LifestyleTransient()
);
IocManager.IocContainer.Register(
用于()的组件
.由()实施
.已命名(“电子邮件”)
.生活方式
);
当前ABP版本:3.7.1

这是我到目前为止掌握的信息。如果需要什么,你可以在评论中询问

//向租户的所有订阅使用发送通知
_发布(AppNotificationNames.EventCreated);
如果您像这样发布通知,ABP的默认实现是

后台作业中没有会话

您可以通过以下方式获得
tenantId

IocManager.IocContainer.Register(
    Component.For<IRealTimeNotifier>()
        .ImplementedBy<EmailNotifier>()
        .Named("Email")
        .LifestyleTransient()
);
var tenantId=userNotifications[0]。Notification.tenantId;
using(AbpSession.Use(tenantId,null))
{
// ...
}

很抱歉延迟响应,是的,它成功了!非常感谢。