title: Best approach to combine repositories logic
body: <p><strong>Let's suppose I have 2 <code>repositories</code>:</strong></p>
  <ul>
  <li>first is responsible for creating job and return <code>jobId</code></li>
  <li>second is responsible for creating log and take <code>jobId</code> as argument</li>
  </ul>
  <p><strong>My goal is to:</strong></p>
  <ul>
  <li>save <code>Job</code> and <code>Log</code> simultaneously</li>
  <li>prevent situation when in case of error only <code>Job</code> would be saved without <code>Log</code></li>
  </ul>
  <h3>What is the most recommended way to get desired result?</h3>
  <p>I prepared 3 cases which came to my mind but if you see better alternative please share it.</p>
  <ul>
  <li><strong>option 1 (getting result and save changes in controller)</strong></li>
  </ul>
  <pre class="lang-cs prettyprint-override"><code>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(&quot;Index&quot;);
      }
  }
  </code></pre>
  <ul>
  <li><strong>option 2 (inject one repository into another)</strong></li>
  </ul>
  <pre class="lang-cs prettyprint-override"><code>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(&quot;Index&quot;);
      }
  }
  </code></pre>
  <ul>
  <li><strong>option 3 (do not use context in controller but declare <code>Save</code> method in each repo)</strong></li>
  </ul>
  <pre class="lang-cs prettyprint-override"><code>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(&quot;Index&quot;);
      }
  }
  </code></pre>