List query object support in the repository

We have seen the GetAllPosts method, which includes related data for all implementations. Since we are creating a common query, which could be consumed in multiple places, we need to include this as a filter in the GetAllPostsQuery object:

    public class GetAllPostsQuery
{
public GetAllPostsQuery(bool includeData)
{
this.IncludeData = includeData;
}
public bool IncludeData { get; set; }
}

The GetAllPostsQuery consumes only the IncludeData filter in the type, which doesn't filter any data from the result set, but only excludes/includes related data. The following code would create a contract to enforce consumers to implement handle methods:

    public interface IPostQueryHandler<T> where T : class
{
IEnumerable<Post> Handle(T query);
Task<IEnumerable<Post>> HandleAsync(T query);
}

The generic query handler interface now supports both synchronous and asynchronous operations, which returns a list of Posts. The GetAllPostsQueryHandler would perform the concrete implementation which will yield a list of Posts in synchronous and asynchronous manner as displayed in the following code:

    public class GetAllPostsQueryHandler :
IPostQueryHandler<GetAllPostsQuery>
{
private readonly BlogContext _context;
public GetAllPostsQueryHandler(BlogContext context)
{
this._context = context;
}

public IEnumerable<Post> Handle(GetAllPostsQuery query)
{
return query.IncludeData
? _context.Posts.Include(p =>
p.Author).Include(p => p.Blog).Include(p => p.Category).ToList()
: _context.Posts.ToList();
}
public async Task<IEnumerable<Post>>
HandleAsync(GetAllPostsQuery query)
{
return query.IncludeData
? await _context.Posts.Include(p => p.Author).Include(p
=> p.Blog).Include(p => p.Category).ToListAsync()
: await _context.Posts.ToListAsync();
}
}

The GetAllPostsQuery consumes the generic query handler to return all posts with or without including related data. The IPostRepositoryWithQueries will create a contract with Get() and GetAsync() method to retrieve list of Posts with the following code:

    public interface IPostRepositoryWithQueries
{
IEnumerable<Post> Get<T>(BlogContext context, T query)
where T : class;
Task<IEnumerable<Post>> GetAsync<T>(BlogContext context,
T query) where T : class;
}

The PostRepositoryWithQueries repository is created to accommodate the query objects with generic methods to accept any query type for its execution, thereby reducing the multiple methods created in the repository earlier. The concrete implementation of the repository is displayed below which delegates the query execution based on the query type:

    public class PostRepositoryWithQueries : IPostRepositoryWithQueries
{
private readonly BlogContext _context;

public PostRepositoryWithQueries(BlogContext context)
{
_context = context;
}

public IEnumerable<Post> Get<T>(BlogContext context, T query)
where T : class
{
switch(typeof(T).Name)
{
case "GetAllPostsQuery":
var getAllPostsQueryHandler =
new GetAllPostsQueryHandler(context);
return getAllPostsQueryHandler.Handle(query
as GetAllPostsQuery);
}
}

public async Task<IEnumerable<Post>> GetAsync<T>(BlogContext
context, T query)
where T : class
{
switch (typeof(T).Name)
{
case "GetAllPostsQuery":
var getAllPostsQueryHandler = new
GetAllPostsQueryHandler(context);
return await getAllPostsQueryHandler.HandleAsync(query
as GetAllPostsQuery);
}
}
}

The repository's Get generic method changes its implementation based on the type passed during its invocation, and that reduces the repository implementation to one for all post list retrievals. The PostRepositoryWithQueries were consumed in the PostsController as shown in the following code:

    public class PostsController : Controller
{
private readonly BlogContext _context;
private readonly IPostRepositoryWithQueries _repositoryWithQueries;

public PostsController(BlogContext context,
IPostRepositoryWithQueries repositoryWithQueries)
{
_context = context;
_repositoryWithQueries = repositoryWithQueries;
}

// GET: Posts
public async Task<IActionResult> Index()
{
return View(await _repositoryWithQueries.GetAsync(_context,
new GetAllPostsQuery(true)));
}

// Code removed for brevity
}

We can see the controller started using the new repository through dependency injection and corresponding the Get action being called using the appropriate query object. In the preceding scenario, we have been using the GetAllPostsQuery object that was passed on to the GetAsync method of the new repository. In the next section, let's explore the implementation required to return an individual post object from the repository.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset