title: Reduce/remove repetitive business logic checks in ASP.NET Core
body: <p>Is there a way to reduce/remove constant duplication of user access checks (or some other checks) in a business layer?</p>
  <p>Let's consider a following example: simple CRUD application with one entity <code>BlogPost</code>:</p>
  <pre><code>public class BlogPost
  {
      public int Id { get; set; }
      public string Title { get; set; }
      public string Body { get; set; }
  
      public int AuthorId { get; set; }
  }
  </code></pre>
  <p>In PUT/DELETE requests before modifying or deleting entity I need to make a check whether the user that's making request is author of BlogPost, so he is permitted to delete/edit it.</p>
  <p>So both in <code>UpdateBlogPost</code> and <code>DeleteBlogPost</code> of imaginary <code>BlogPostService</code> I'll have to write something like this:</p>
  <pre><code>var blogPostInDb = _blogPostRepository.GetBlogPost();
  
  if(blogPostInDb == null)
  {
      // throw exception or do whatever is needed
  }
  
  if(blogPostInDb.AuthorId != _currentUser.Id)
  {
     // throw exception etc...
  }
  </code></pre>
  <p>This kind of code will be the same for both <code>Update</code>and <code>Delete</code> methods as well as other methods that may be added in future and the same for all entities.</p>
  <p>Is there any way to reduce or completely remove such duplication?</p>
  <p>I thought this over and came up with following solutions, but they don't satisfy me fully.</p>
  <p><strong>First solution</strong></p>
  <p>Using filters. We can create some custom filters like <code>[EnsureEntityExists]</code> and <code>[EnsureUserCanManageEntity]</code> but this way we're spreading some of business logic in our API layer and it's not flexible enough since we need to create such filter for every entity. Perhaps some kind of generic filter can be made using reflection.</p>
  <p><strong>Also</strong> there is another problem with this approach, let's say we've made such filter that's checking our rules. We're fetching entity from db, doing checks, throwing exceptions and all that stuff and letting controller method execute. BUT in service layer we need to fetch entity again, so we're making two roundtrips to db. Maybe I'm overthinking this problem and that's fine to make 2 roundtrips, taking into account that fact that caching can be applied.</p>
  <p><strong>Second solution</strong></p>
  <p>Since I'm using CQRS (or at least some kind of it) I have <a href="https://github.com/jbogard/MediatR" rel="nofollow noreferrer">MediatR</a> library and I can make use of <a href="https://github.com/jbogard/MediatR/wiki/Behaviors" rel="nofollow noreferrer">Pipeline Behaviors</a> and even pass fetched entity further into pipeline via mutating <code>TRequest</code> (which I don't wanna do). This solution requires some common interface for all requests to be able to retrieve id of the entity. The roundtrip problem also applicable here too.</p>
  <pre><code>public interface IBlogPostAccess
  {
      public int Id { get; set; }
  }
  
  public class ChangeBlogPostCommand: IRequest, IBlogPostAccess
  {
      // ...
  }
  
  public class DeleteBlogPostCommand: IRequest, IBlogPostAccess
  {
      // ...
  }
  
  public class BlogPostAccessBehavior&lt;TRequest, TResponse&gt; : IPipelineBehavior&lt;TRequest, TResponse&gt; where TRequest : IBlogPostAccess
  {
      // all nessesary stuff injected via DI
     
      public BlogPostAccessBehavior()
      {
      }
  
      public async Task&lt;TResponse&gt; Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate&lt;TResponse&gt; next)
      {
          var blogPostInDb = _blogPostRepository.GetBlogPost(request.Id);
          if(blogPostInDb == null)
          {
              // throw exception or do whatever is needed
          }
  
          if(blogPostInDb.AuthorId != _currentUser.Id)
          {
             // throw exception etc...
          }
  
          return await next();
      }
  }
  </code></pre>
  <p><strong>Third solution</strong></p>
  <p>Create something like request context service. In a very simplified way it will be a dictionary that will be persisted across request where we can store data (in this case our BlogPost that we've fetched in filter/pipeline). This seems lame and recalls me a <code>ViewBag</code> in ASP.NET MVC.</p>
  <p><strong>Fourth solution</strong></p>
  <p>It's more enhancement than a solution, but we can use <code>GuardClause</code> or extension methods to reduce nesting of <code>if</code> statements.</p>
  <p>Again, maybe I'm overthinking this problem or it's not a problem at all or that's a design issue. Any help, thoughts appreciated.</p>