【发布时间】:2020-04-19 14:54:14
【问题描述】:
我有一个 .NET Core 3.1 应用程序。应用程序应发送电子邮件,并在电子邮件成功(或未成功)发送到 SQL Server 数据库时记录。
我已经在Startup.cs注册了数据库:
services.AddDbContext<DataBaseAppContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
我已经在同一个文件中注册了我的电子邮件发件人,如下所示:
services.AddTransient<IEmailSender, EmailSender>();
这是EmailSender 的实现:
public class EmailSender : IEmailSender
{
private readonly DataBaseAppContext _context;
public EmailSender(DataBaseAppContext context)
{
_context = context;
}
public Task SendEmailAsync(string subject, string message, string email)
{
return Execute(subject, message, email);
}
public Task Execute(string subject, string message, string email)
{
try
{
MailAddress fromAddress = new MailAddress(...);
SmtpClient smtp = new SmtpClient
{
Host = ...,
Port = ...,
...
};
MailMessage md = new MailMessage
{
From = ...,
IsBodyHtml = true,
Subject = subject,
Body = message,
To = ...
};
smtp.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
if (e.Cancelled)
{
//Want to use this statement as well, to log errors
}
if (e.Error != null)
{
//Want to use this statement as well, to log errors
}
else
{
try
{
//Object that should be saved in DB
EmailLogger emailLogger = new EmailLogger()
{
Email = email,
Subject = subject,
Message = message,
DateTime = DateTime.Now
};
_context.EmailLogger.Add(emailLogger);
_context.SaveChanges();
}
catch(Exception ex)
{
//Here I got an error - the *error below
}
}
}
return smtp.SendMailAsync(md);
}
catch (Exception e)
{
throw e;
}
}
}
每当我拨打EmailSender.SendEmailAsync 时,我都会收到以下错误:
无法访问已处置的对象。此错误的一个常见原因是释放从依赖注入中解析的上下文,然后尝试在应用程序的其他地方使用相同的上下文实例。如果您在上下文上调用 Dispose() 或将上下文包装在 using 语句中,则可能会发生这种情况。如果你使用依赖注入,你应该让依赖注入容器负责处理上下文实例。
我知道这是因为服务注册为AddTransient,而_context在回调发生时已经被释放。
不确定解决此问题的最佳方法是什么,尝试将AddTransient 更改为AddScoped 或AddSingleton 只是为了看看会发生什么,但随后Program.cs 出现错误。
【问题讨论】:
标签: c# dependency-injection callback smtp dbcontext