У меня есть приложение. NET Core 3.1. Приложение должно отправлять электронные письма и регистрироваться, когда электронное письмо успешно отправлено (или нет) в SQL Серверную базу данных.
Я зарегистрировал базу данных в 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
.