title: Using the DbContext the SOLID way
body: <p>By depending directly on the <code>DbContext</code> in command- and query handlers, I understand that I am violating the <a href="https://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29" rel="nofollow noreferrer">SOLID-principles</a> as of this comment from a <a href="https://codereview.stackexchange.com/questions/87876/allowing-query-handlers-to-use-other-query-handlers/101100#comment185335_101100">StackOverflow user</a>:</p>
  
  <blockquote>
    <p>The <code>DbContext</code> is a bag with request-specific runtime data and
    injecting runtime data into constructors causes trouble. Letting your
    code having a direct dependency of on <code>DbContext</code> causes your code to
    violate DIP and ISP and this makes hard to maintain.</p>
  </blockquote>
  
  <p>This makes totally sense, but I am unsure how to solve it probably using IoC and DI? </p>
  
  <p>By initial though was to create a <code>IUnitOfWork</code> with a single method which could be used to query the context:</p>
  
  <pre><code>public interface IUnitOfWork
  {
      IQueryable&lt;T&gt; Set&lt;T&gt;() where T : Entity;
  }
  
  internal sealed class EntityFrameworkUnitOfWork : IUnitOfWork
  {
      private readonly DbContext _context;
  
      public EntityFrameworkUnitOfWork(DbContext context)
      {
          _context = context;
      }
  
      public IQueryable&lt;T&gt; Set&lt;T&gt;() where T : Entity
      {
          return _context.Set&lt;T&gt;();
      }
  } 
  </code></pre>
  
  <p>Now that I can depend on <code>IUnitOfWork</code> in my query handlers (receiving data), I have solved this part. </p>
  
  <p>Next I needed to look at my commands (modifying data) I could solve the saving of changes to the context with a decorator for my commands:</p>
  
  <pre><code>internal sealed class TransactionCommandHandler&lt;TCommand&gt; : IHandleCommand&lt;TCommand&gt; where TCommand : ICommand
  {
      private readonly DbContext _context;
      private readonly Func&lt;IHandleCommand&lt;TCommand&gt;&gt; _handlerFactory;
  
      public TransactionCommandHandler(DbContext context, Func&lt;IHandleCommand&lt;TCommand&gt;&gt; handlerFactory)
      {
          _context = context;
          _handlerFactory = handlerFactory;
      }
  
      public void Handle(TCommand command)
      {
          _handlerFactory().Handle(command);
          _context.SaveChanges();
      }
  }
  </code></pre>
  
  <p>This works fine as well. </p>
  
  <p>First question is: <strong>How do I modify objects in the context from my command handlers, as I can not depend directly on the DbContext anymore?</strong></p>
  
  <p>Like: <code>context.Set&lt;TEntity&gt;().Add(entity);</code></p>
  
  <p>As far as I understand I have to create another interfaces for this to work with the SOLID-principles. For example a <code>ICommandEntities</code> which would contain methods like <code>void Create&lt;TEntity&gt;(TEntity entity)</code>, update, delete, rollback and even reload. Then depend on this interface in my commands, but am I missing a point here and are we abstracting too deep?</p>
  
  <p>Second questions is: <strong>Is this the only way respect the SOLID-principles when working with the DbContext or is this a place where its "okay" to violate the principles?</strong></p>
  
  <p>If needed, I use Simple Injector as my IoC container.</p>