【问题标题】:Best approach to combine repositories logic组合存储库逻辑的最佳方法
【发布时间】:2022-01-02 01:28:53
【问题描述】:

假设我有 2 个repositories

  • first 负责创建工作并返回jobId
  • second负责创建日志并以jobId为参数

我的目标是:

  • 同时保存JobLog
  • 防止出现错误时只保存Job 而没有Log

获得理想结果的最推荐方法是什么?

我准备了 3 个我想到的案例,但如果您看到更好的选择,请分享。

  • 选项 1(在控制器中获取结果并保存更改)
public class JobRepository : IJobRepository
{
    private readonly Context _context;
    
    public JobRepository(Context context)
    {
        _context = context;
    }

    public Guid CreateJob()
    {
        var job = new Job { Id = Guid.NewGuid() };
        _context.Jobs.Add(job);
        return job.Id;
    }
}
// ...
public class LogRepository : ILogRepository
{
    private readonly Context _context;
    
    public LogRepository(Context context)
    {
        _context = context;
    }

    public void CreateLog(Guid id)
    {
        var log = new Log { Jobid = id };
        _context.Logs.Add(log);
    }
}
// ...
public class JobsController : Controller
{
    private readonly Context _context;
    private readonly IJobRepository _jobRepository;
    private readonly ILogRepository _logRepository;

    public JobsController(Context context, JobRepository jobRepository, ILogRepository logRepository)
    {
        _context = context;
        _jobRepository = jobRepository;
        _logRepository = logRepository
    }

    [HttpGet]
    public IActionResult Create()
    {
        return View();
    }

    [HttpPost]
    public IActionResult Create()
    {
        var id = _jobRepository.CreateJob();
        _logRepository.CreateLog(id);
        _context.SaveChanges();
        return RedirectToAction("Index");
    }
}
  • 选项 2(将一个存储库注入另一个存储库)
public class JobRepository : IJobRepository
{
    private readonly Context _context;
    private readonly ILogRepository _logRepository;
    
    public JobRepository(Context context, ILogRepository logRepository)
    {
        _context = context;
    }

    public void CreateJob()
    {
        var job = new Job { Id = Guid.NewGuid() };
        _context.Jobs.Add(job);
        _logRepository.CreateLog(job.Id);
        _context.SaveChanges();
    }
}
// ...
public class LogRepository : ILogRepository
{
    private readonly Context _context;
    
    public LogRepository(Context context)
    {
        _context = context;
    }

    public void CreateLog(Guid id)
    {
        var log = new Log { Jobid = id };
        _context.Logs.Add(log);
    }
}
// ...
public class JobsController : Controller
{
    private readonly IJobRepository _jobRepository;

    public JobsController(JobRepository jobRepository)
    {
        _jobRepository = jobRepository;
    }

    [HttpGet]
    public IActionResult Create()
    {
        return View();
    }

    [HttpPost]
    public IActionResult Create()
    {
         _jobRepository.CreateJob();
        return RedirectToAction("Index");
    }
}
  • 选项 3(不要在控制器中使用上下文,而是在每个 repo 中声明 Save 方法)
public class JobRepository : IJobRepository
{
    private readonly Context _context;
    
    public JobRepository(Context context)
    {
        _context = context;
    }

    public Guid CreateJob()
    {
        var job = new Job { Id = Guid.NewGuid() };
        _context.Jobs.Add(job);
        return job.Id;
    }

    public void Save()
    {
        _context.SaveChanges();
    }
}
// ...
public class LogRepository : ILogRepository
{
    private readonly Context _context;
    
    public LogRepository(Context context)
    {
        _context = context;
    }

    public void CreateLog(Guid id)
    {
        var log = new Log { Jobid = id };
        _context.Logs.Add(log);
    }

    public void Save()
    {
        _context.SaveChanges();
    }
}
// ...
public class JobsController : Controller
{
    private readonly IJobRepository _jobRepository;
    private readonly ILogRepository _logRepository;

    public JobsController(JobRepository jobRepository, ILogRepository logRepository)
    {
        _jobRepository = jobRepository;
        _logRepository = logRepository
    }

    [HttpGet]
    public IActionResult Create()
    {
        return View();
    }

    [HttpPost]
    public IActionResult Create()
    {
        var id = _jobRepository.CreateJob();
        _logRepository.CreateLog(id);
        return RedirectToAction("Index");
    }
}

【问题讨论】:

标签: c# .net asp.net-mvc


【解决方案1】:

正如用例所示,操作(保存和日志记录)应作为单个工作单元进行。

我建议采用类似于第三种方法的方法。但不是直接将两个存储库注入控制器。我们可以创建一个服务,然后使用这些存储库。

这里我们可以创建如下服务:

    public class JobService : IJobService
    {
        private readonly IJobRepository _jobRepo;
        private readonly ILogRepository _logRepo;

        public JobRepository(IJobRepository jobRepo, ILogRepository logRepo)
        {
            _jobRepo = jobRepo;
            _logRepo = logRepo;
        }

        public void CreateJob()
        {
            var id = _jobRepo.CreateJob();
            _logRepo.CreateLog(id);
        }
    }

    public class JobsController : Controller
    {
        private readonly IJobService _jobService;

        public JobsController(IJobService jobService)
        {
            _jobService = jobService;
        }

        [HttpGet]
        public IActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public IActionResult Create()
        {
            _jobService.CreateJob();
            return RedirectToAction("Index");
        }
    }

补充阅读:The Repository-Service pattern

【讨论】:

    猜你喜欢
    • 2014-05-20
    • 1970-01-01
    • 1970-01-01
    • 2012-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-07
    • 2021-10-31
    相关资源
    最近更新 更多