EF6 Windows服务中的存储库模式

问题描述:

我已经实现了一项Windows服务,它将从数据库中获取电子邮件列表,并每隔60秒使用.net邮件发送它们。 我已经使用存储库模式设计了它,请参阅解决方案文件夹和项目的屏幕截图。 Click to see the pictureEF6 Windows服务中的存储库模式

问题:

  1. 在图案方面我是在正确的轨道上?分离项目的结构,为每个存储库和每个存储库的服务创建一个接口。
  2. 如果某些业务逻辑与数据库无关,是否还需要为它们创建存储库或者服务是否足够?
  3. 我有一个SMTP服务类实现.net邮件和发送电子邮件,而我发送每个电子邮件我需要更新数据库,我想知道是否将更新逻辑放在SMTP服务类是一个好的做法?这有点像下面

    public class SMTPService : ISMTPService 
        { 
    
         SmtpClient client; 
         MailMessage newMessage; 
         EmailService emailService; 
         IEventLoggerService MailCheckerLog; 
    
         public async Task SendEmail(tb_Email email) 
         {...} 
    
         void SendCompletedCallback(object sender, System.ComponentModel.AsyncCompletedEventArgs e, tb_Email email) 
         { 
    
          if (e.Cancelled) 
          { 
    
          } 
          if (e.Error != null) 
          { 
    
          } 
          else 
          { 
           email.DateSent = DateTime.Now; 
           emailService.Update(email); 
          } 
    
          client.Dispose(); 
          newMessage.Dispose(); 
    
         } 
    

    }

我不知道你想什么,实现准确,你有什么样的业务需求。

现在的结构是可以的,但考虑一下:你有一个用户实体和一个照片实体。每个用户必须有与他们相关的照片。你将如何处理这种情况?

您必须创建UserRepository和PhotoRepository。您首先必须插入用户记录以便照片记录稍后参考。 所以你调用UserRepository的Insert()方法。插入用户时,您可以调用PhotoRepository的Insert()方法。但是,如果该Insert()失败?现在你有一个没有照片的db用户。

您必须在一次交易中将用户和照片放在一起。这就是工作单元模式的来源。如果您的业务逻辑涉及多个实体类型,则必须使用该模式。如果你所做的只是处理电子邮件,那么这很好。如果不是,则必须将该模式添加到您的应用程序中。看一个例子here

服务也是处理业务事务的事物,而业务事务可以触及多种类型的事件。同样,工作单元模式可以帮助你解决这个问题。但通常存储库是根据您的实体和基于您的业务逻辑的服务创建的。在这个例子中,你可以有一个同时使用UserRepository和PhotoRepository的UserService(通常通过工作单元)。

在发送电子邮件的情况下,我会再次根据我的业务逻辑设计服务。业务逻辑可能是“发送电子邮件”,而不是“通过SMTP发送电子邮件”。如果您决定使用SendGrid之类的服务,会发生什么情况?那么它不再是SMTPService了。

我可能会创建一个EmailService(你也有),这将有一个SendEmails()方法。这将使用EmailRepository来获取电子邮件,使用SMTP发送它,然后更新它并通过工作单元进行保存。或者,如果你想真正抽象,你可以用一种方法,SendEmail(电子邮件电子邮件)创建一个IEmailSenderService接口。然后,您可以创建一个SmtpEmailSenderService,它实现此接口并包装SmtpClient类并使用SMTP发送电子邮件。如果您决定转移到SendGrid,则可以创建一个SendGridEmailSenderService,它使用HttpClient向SendGrid发出请求。更新仍然使用存储库和工作单元在EmailService中完成,但现在EmailService本身不使用SmtpClient,而只使用IEmailSenderService接口。

+0

感谢您的回复,我只有一个电子邮件实体。我还需要UOW吗?因为我听说当我们有多个实体时这很有用。 – user65248

+0

如果你只有一个实体,那么你不需要这个实体。 –

+0

出于好奇,目前我使用SendMailAsync来发送SendComplete事件时发送电子邮件和处理数据库更新。由于我在一批中发送超过100封电子邮件,有时SendComplete在下一封电子邮件正在处理之前未被解雇,因此我通过在dbcontext的使用语句中包装我的更新方法来为每个事务使用新的dbco0ntext,如下所示(BBEntities db = new BBEntities()) db.Entry(obj).State = EntityState.Modified; db.SaveChanges(); } – user65248