← Back to knowledge base |
  • Xperience by Kentico

Guide to Repository pattern with a Generic type in Xperience by Kentico

The Repository pattern in C# is a design pattern used to manage data retrieval from a data source. It acts as a mediator between the data access layer and the business logic layer of an application. When working with websites built on Xperience by Kentico, we often focus on fetching data from the database, and this is where the repository pattern becomes invaluable. In this guide, I'll walk you through the process of creating repositories that retrieve data from the Xperience by Kentico database. We'll use generic types and focus on Reusable content and Pages content types. This approach simplifies data access and enhances your website's performance and maintainability.

Solution outline

In our final solution, we'll have four key files:

  • ContentRepositoryModel.cs - This file outlines the types for method parameters used across the other files.
  • WebPageRepository.cs and ReusableContentRepository.cs - These files implement the methods that define data fetching queries, cache keys, and cache dependencies.
  • ContentRepositoryBase.cs - This file handles the actual data fetching, including data cache management.

In a Kentico Xperience project, these files typically reside in the Models folder. They sit alongside the types that are generated from your content types, which are defined in the Kentico Xperience admin interface.

Source code is also available as a Github gist.

The ContentRepositoryModel.cs file

The ContentRepositoryModel.cs file primarily defines types for method parameters used in other files, which we'll explore later in this article. I've chosen this approach over named parameters for clarity, especially as the number of parameters can increase as your site becomes more complex. Additionally, these grouped parameters, defined through types, are reused across multiple methods, promoting code consistency and maintainability.

Loading...

The WebPageRepository.cs file

The WebPageRepository class implements a single public method that creates a data fetching query, data cache keys and dependencies. The actual implementation of the method may vary depending on your requirements. You can also create multiple methods like this if needed. My implementation fetches pages specified by their WebPageItemGUID for a specific web page content type. If no guid is provided, the method fetches all items of the specified type. 

Loading...

Let's delve deeper into the code:

  • The WebPageRepository class extends the ContentRepositoryBase base class, sharing data fetching logic with the class defined in the ReusableContentRepository.cs file.
  • The constructor employs the dependency injection pattern.
  • The GetPages method:
    • Accepts a generic type T that represents a web page content type model. It must implement the IWebPageFieldsSource interface, enabling the repository to be used for any web page content type.
    • Constructs a query to retrieve content items from the database. In this case, we're requesting pages based on the content type represented by the T type, including linked items within a specified depth, ordered by the sequence defined in the Xperience by Kentico admin, and limiting the result items by their GUID.
    • Specifies the cache key's name and the duration for which the data should be cached, provided the cache revalidation is invoked by the cache dependency key specified in the GetDependencyCacheKeys method. This method also ensures that caching is managed for linked items.
    • Retrieves data by calling the GetCachedQueryResult method, which is defined in the base class. I will describe this method in more detail later in this article. 

The ReusableContentRepository.cs file

This file mirrors the repository implementation for web pages. While the purpose and logic remain largely the same, the implementation details vary slightly as it fetches data for reusable content items. 

Loading...

The ContentRepositoryBase.cs file

This file embodies the logic shared between the WebPageRepository.cs and ReusableContentRepository.cs files. It handles data retrieval, taking into account both preview data and data caching.

Loading...

The GetCachedQueryResult method scrutinizes incoming parameters, while the actual logic unfolds in the GetCachedQueryResultInternal method:

  • If data retrieval occurs in the context of Preview mode or within a Page builder, it bypasses the data cache and always fetches fresh data.
  • Otherwise, it attempts to retrieve data from the data cache based on CacheSettings. If the data is not available in the cache, it requests them from the database and stores them in the cache for future use. 

Example of usage

This repository patter then of course could be used for retrieving web pages or content items in your controllers, widgets, or view components. 

Web page retrieval in a controller

Loading...

In the example, we define a controller for a page based on specific content type:

  • It retrieves context of the current page using webPageDataContextRetriever which includes the GUID we will uses for the data retrieval using the repository.
  • It retrieves the page by GUID using the repository and passing cancellation token that ensures freeing up resources when an ongoing request gets aborted.
  • If no page is retrieved, we consider it as page not found.
  • Otherwise, we build the view model and pass it in the view for final rendering.

Reusable content retrieval example

In a very similar fashion you can obtain content items using the repository:

Loading...

Conclusion

In conclusion, the outlined solution provides a robust and flexible approach to data retrieval in a Xperience by Kentico project. The four key files - ContentRepositoryModel.cs, WebPageRepository.cs, ReusableContentRepository.cs, and ContentRepositoryBase.cs - work in unison to define data fetching queries, manage data cache, and handle data fetching.

The ContentRepositoryModel.cs file provides a clear and maintainable way to define method parameters, while the WebPageRepository.cs and ReusableContentRepository.cs files implement the methods that define data fetching queries, cache keys, and cache dependencies. The ContentRepositoryBase.cs file, on the other hand, handles the actual data fetching, including data cache management.

This solution also takes into account the context of data retrieval, ensuring fresh data is fetched in Preview mode or within a Page builder, and otherwise retrieving data from the cache or database as needed.

Source code for this post is available as a Github gist.

 

About the author

Milan Lund is a freelance web developer with expertise in Kentico. He specializes in building and maintaining websites on the Kentico platform. Milan writes articles based on his project experiences to assist both his future self and other developers.

Find out more
Milan Lund