微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

设计模式 – DDD审计?域层或存储库层?

我目前正在处理的应用程序要求在数据库中对每个数据库进行审计:

例如:员工表有EmployeeAuditTable

我一直在讨论我应该把审计功能放在哪里! DDD之后,任何人都可以向我提供他们的建议和意见.

我想到的选项如下
1.)当“存储库”调用保存更改时,我应该从存储库执行审计逻辑(这个糟糕的设计/实践是否使存储库不仅保持更改而且还保持审计细节?这是否是良好的做法从存储库中调用服务(在本例中为IAuditService))

例1:

public class EmployeeRepository : IRepository
{
    DbContext _db;
    IAuditService _auditService;

    EmployeeRepository(IAuditService auditService)
    {
      _auditService = auditService
    }
    void Update(Employee empl)
    {
        // Update Employee with dbcontext entity framework

        // Perform Audit using AuditService
    }

   void SaveChanges()
   {
      // Call save changes on dbcontext
   }

}

2.)我应该在我的应用程序服务中调用IAuditService

例2:

public class EmployeeService
{
   IAuditService _auditService;
   IUnitOfWork   _unitOfWork;
   IEmployeeRepository _repository;

   EmployeeService(IAuditService auditService,IUnitOfWork  unitOfWork,IEmployeeRepository repo)
   {
       _auditService = auditService;
       _unitOfWork= unitOfWork;
       _repo  = repo;
   }

   void UpdateEmployee(int id,string name,int age)
   {
      // Get Employee

      // Update Employee

      // Audit Changes

      // Commit Transaction

   }


}

解决方法

我知道您希望对数据库中的所有对象进行审计跟踪,但我不会监视问题的完整复杂性.您的Employee和EmployeeAuditTable的外观并不十分清楚,但所选的命名约定表明它包含与employee表相同的列.

审计可以并且通常被认为是“跨领域的关注”.当您有“应审核所有更改”等要求时尤其如此.如果审计不是业务问题(或用例或您称之为的任何内容),则不应将其放在您的实体,服务或存储库中;如果只是因为在审计中忘记编码是非常非常容易的,那么会留下不正确的审计线索 – 有些人认为这比没有审计线索更糟糕.

从您的代码示例中,我看到您正在使用一个工作单元.我想象一下

// commit transaction

您提交工作单元跟踪的更改:

// commit transaction
_unitOfWork.Commit();

同样,它承诺由工作单元跟踪的更改.有您的审计挂钩点,它不需要涉及任何服务,实体或存储库中的编码.

事实上,当您使用像(N)Hibernate这样的ORM框架时,您可以让ORM跟踪您的更改(它将挂钩到其工作单元),例如参见the wiki page “creating an audit log using events”Envers审计框架NHibernate,也在0700讨论过.我强烈建议您阅读Envers文档,即使您实施自己的审计解决方案.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐