Promoting SoC Through Application Layering

Creating a layered design in an application is a fundamental element of modern software architecture. The goal is to promote the Separation of Concerns (SoC) design principle. Separation of Concerns The ideas behind SoC date back to Dijkstra's 1974 paper "On the role of scientific thought" . In computer science, separation of concerns (sometimes abbreviated as SoC) is a design principle for separating a computer program into distinct sections. Each section addresses a separate concern, a set of information that affects the code of a computer program. A concern can be as general as "the details of the hardware for an application", or as specific as "the name of which class to instantiate". A program that embodies SoC well is called a modular program. Modularity, and hence separation of concerns, is achieved by encapsulating information inside a section of code that has a well-defined interface. - Wikipedia SoC is a broad design principal th...

Caching in ASP.NET

Caching data is a critical feature for application performance. In ASP.NET applications, caching is fairly simple using the MemoryCache ServiceCollection extension.

Caching Example Application Screen Shot

The following interface and class show how we can easily read and write data from the MemoryCache.

public interface ICachedData
{
	List<Widget> GetWidgets();
}

public class CachedData : ICachedData
{
	private readonly IMemoryCache _memoryCache;

	private readonly string CacheKeyWidgets = "Widgets";

	public CachedData(IMemoryCache memoryCache) 
	{
		_memoryCache = memoryCache;
	}

	public List<Widget> GetWidgets()
	{
		var result = _memoryCache.Get(CacheKeyWidgets) as List<Widget>;

		if (result == null)
		{
			// load data for cache, this could be a WebAPI or WCFService call
			result = new List<Widget>()
			{
				new Widget()
				{
					Id = 1,
					Name = "Widget1",
					Description = "Widget 1",
					Price = 1m
				},
				new Widget()
				{
					Id = 2,
					Name = "Widget2",
					Description = "Widget 2",
					Price = 10m
				},
				new Widget()
				{
					Id = 3,
					Name = "Widget3",
					Description = "Widget 3",
					Price = 100m
				}
			};

			// add the data to the cache, in this demo we just cache data for 20 minutes
			_memoryCache.Set(CacheKeyWidgets, result, new MemoryCacheEntryOptions()
			{
				AbsoluteExpiration = DateTime.UtcNow.AddMinutes(20)
			});
		}

		return result;
	}
}

To use the above class, we just need to register the MemoryCache and CachedData class in the application. The following code needs to be added to Program.cs.

builder.Services.AddMemoryCache();

builder.Services.AddSingleton<ICachedData, CachedData>();

Here is an example Index.cshtml.cs showing how to use CacheData.

public class IndexModel : PageModel
{
	private readonly ILogger<IndexModel> _logger;
	private readonly ICachedData _cachedData;

	public List<Widget> Widgets { get; set; } = new List<Widget>();

	public IndexModel(ILogger<IndexModel> logger, ICachedData cachedData)
	{
		_logger = logger;
		_cachedData = cachedData;
	}

	public void OnGet()
	{
		Widgets = _cachedData.GetWidgets();
	}
}

This example was created using Visual Studio 2022 running an ASP.NET Core Web App project using IIS Express.

Source code: https://github.com/jharrell-bits/WebAppCachingDemo