smtpclient가 실패 할 때 데이터베이스에 리트 로그로 비동기 메일을 보내려고합니다. WebAPI 2.2 + EF6 + Autofac을 사용하고 있습니다. 오류 메시지 :SmtpClient를 사용하여 메일을 보낸 후 처리 된 DbContext
DbContext가 삭제 되었기 때문에 작업을 완료 할 수 없습니다.
내 주요 부호 :
public class SMTPEmailSender : IEmailSender
{
[...]
public void SendMailAsync(string templateKey, object model, string subject, MailAddress fromAddress, List<MailAddress> toAddresses,
List<MailAddress> ccAddresses = null, List<MailAddress> replyTo = null)
{
try
{
var htmlBody = GenerateHtmlBody(templateKey, model);
var client = new SmtpClient();
var message = new MailMessage
{
From = fromAddress,
Subject = subject,
IsBodyHtml = true,
Body = htmlBody
};
toAddresses.ForEach(m => message.To.Add(m));
if (ccAddresses != null) ccAddresses.ForEach(m => message.CC.Add(m));
if (replyTo != null) replyTo.ForEach(m => message.ReplyToList.Add(m));
client.SendCompleted += SendCompletedCallback;
client.SendAsync(message, message);
}
catch (Exception ex)
{
throw new Exception("Error: " + ex.Message + "<br/><br/>Inner Exception: " + ex.InnerException);
}
}
private void SendCompletedCallback(object s, AsyncCompletedEventArgs e)
{
SmtpClient callbackClient = s as SmtpClient;
MailMessage callbackMailMessage = e.UserState as MailMessage;
var regData = SenderMailLogModel(callbackMailMessage);
if (e.Cancelled)
{
try
{
callbackClient.Send(callbackMailMessage);
}
catch (Exception ex)
{
regData.EmailSenderStatus = EmailSenderStatuses.Cancelled;
regData.Exception = ex.Message;
}
}
if (e.Error != null)
{
regData.EmailSenderStatus = EmailSenderStatuses.Error;
regData.Exception = e.Error.ToString() + " in SendCompletedHandlerEvent";
}
_dbContext.EmailSenderLogs.Add(regData); //here fails
_dbContext.SaveChanges();
callbackClient.Dispose();
callbackMailMessage.Dispose();
}
[...]
}
내를 DataContext는 Autofac 의해 분사된다. 내 컨테이너 빌더 구성 :
[...]
containerBuilder.RegisterType<DbEntities>().AsSelf().InstancePerRequest();
containerBuilder.RegisterType<SMTPEmailSender>().As<IEmailSender>().InstancePerRequest();
[...]
내가 이것에 대한 해키 솔루션이 새 DbEntities 객체를 생성하고 대신 autofac 주입 객체를 사용할 수 있습니다.
이것은 'InstancePerRequest'를 사용하기 때문에 발생합니다. 메일이 보내지기 전에 발생하는'HttpContext'로'Application_EndRequest'가 발생할 때'DbContext'를 처리 할 것입니다. 'DbEntities' 평생 동안 어떤 종류의 하이브리드 범위가 필요합니다. AutoFac이 이것을 제공하는지 확실하지 않지만 SimpleInjector는이를 제공합니다. http://simpleinjector.readthedocs.org/en/latest/lifetimes.html – danludwig
Autofac은 하이브리드 수명을 제공합니다. 나는 일생의 범위와 처분이 어떻게 작동하는지 잘 모른다. 내 프로젝트를 단순 주입기로 옮기기를 원했는데, 간단하고 빠른 것처럼 보입니다. – Daniel
SimpleInjector는 IMO로 작업하는 것을 매우 기쁘게 생각합니다. IoC 도구는 훌륭한 도구입니다. – danludwig