vTCacheSyncMaster 1.1.1

dotnet add package vTCacheSyncMaster --version 1.1.1                
NuGet\Install-Package vTCacheSyncMaster -Version 1.1.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="vTCacheSyncMaster" Version="1.1.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add vTCacheSyncMaster --version 1.1.1                
#r "nuget: vTCacheSyncMaster, 1.1.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install vTCacheSyncMaster as a Cake Addin
#addin nuget:?package=vTCacheSyncMaster&version=1.1.1

// Install vTCacheSyncMaster as a Cake Tool
#tool nuget:?package=vTCacheSyncMaster&version=1.1.1                

vTCacheSyncMaster

I'm thrilled to announce the release of my 2nd new NuGet package: vTCacheSyncMaster is a powerful caching solution that seamlessly integrates with various distributed cache providers. These providers include Redis, Azure CosmosDB, SQL Server, Memory Cache, and NCache. Also it will help you optimize your code to single line! If the requested data is unavailable in the cache, the package will automatically call an external API to retrieve it, based on the model class setup in the appsettings.json or any settings file and easily change the cache server by modifying appsettings.json without changing the C# code.

Key Features

  • Robust Caching: Manage and synchronize data across multiple cache providers, reducing latency and improving performance.
  • Effortless Data Access: Fetch, insert, update, or remove cache keys and their associated data. If data isn't found, the package triggers an API call to ensure you always have the latest information.
  • Configuration via settings file: You can set up the caching behavior by configuring the model classes in your appsettings.json or any settings file. This flexibility allows you to tailor caching strategies to your specific use case. Easily change the cache server by modifying appsettings.json without changing the C# code.
  • Flexible Configuration for Cache Services: vTCacheSyncMaster allows you to configure either a single cache service or multiple cache services based on your application's requirements. Whether you need a unified cache solution or want to leverage different providers for specific scenarios, vTCacheSyncMaster adapts seamlessly.

From Verbose to Single Line Bliss

Here's an example of how you can optimize your code to a single line using vTCacheSyncMaster:

const string todosKey = "todos";
IEnumerable<Todo>? todos;

// Original Code
var cachedTodos = await cache.GetStringAsync(todosKey);

if (!string.IsNullOrEmpty(cachedTodos))
{
    todos = JsonSerializer.Deserialize<IEnumerable<Todo>>(cachedTodos);
}
else
{
    var httpClient = httpClientFactory.CreateClient();
    todos = await httpClient.GetFromJsonAsync<IEnumerable<Todo>>("https://jsonplaceholder.typicode.com/todos");

    await cache.SetStringAsync(todosKey, JsonSerializer.Serialize(todos), new DistributedCacheEntryOptions
    {
        AbsoluteExpirationRelativeToNow = new TimeSpan(0, 0, 60)
    });
}

return todos;
Optimized Code

You can simplify the above code to a single line:

var result = await _cacheSyncMaster.GetRecordAsync<IEnumerable<Todo>>(
    "todos", //CacheKey
    new { value = "todos" }  //InputParam for API
);

Getting Started with vTCacheSyncMaster

Installation

Install the package via NuGet:

Install-Package vTCacheSyncMaster
Configuration

In your Startup.cs (or Program.cs for minimal API in .NET 6+): Ensure appsettings.json or your chosen settings file is loaded and bound to the configuration object:

using CacheSyncMaster;

public IConfiguration Configuration { get; }

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public void ConfigureServices(IServiceCollection services)
{
    services.AddCacheSyncMaster(options =>
    {
        options.configuration = this.Configuration;  // Pass the IConfiguration object to CacheSyncMaster
    });

    // Other service configurations
}

The CacheSyncMaster package will internally read and use the cache configuration passed via the IConfiguration object.

Inject the Service

Inject the ICacheSyncMaster service into your classes where you need to use it:

public class YourService
{
    private readonly ICacheSyncMaster _cacheSyncMaster;

    public YourService(ICacheSyncMaster cacheSyncMaster)
    {
        _cacheSyncMaster = cacheSyncMaster;
    }

    public async Task<YourDto> FetchYourData(string inputParam1, string inputParam2)
    {
        var result = await _cacheSyncMaster.GetRecordAsync<YourDto>(
            "YourCacheKey", 
            new { inputParam1 = inputParam1, inputParam2 = inputParam2 }
        );

        return result.Result;
    }
}
Configuration

The caching behavior is defined in your appsettings.json or any settings file. Below is an example setup that integrates Azure CosmosDB, Redis, Memory Cache, and NCache:

{
  "CacheService": {
    "CosmosService": {
      "ContainerName": "YourContainerName",  // Replace with your Azure CosmosDB container name
      "DatabaseName": "YourDatabaseName",  // Replace with your Azure CosmosDB database name
      "ConnectionString": "YourCosmosConnectionString",  // Replace with your Azure CosmosDB connection string
      "CreateIfNotExists": true,  // Set true to create container if it does not exist
      "ModalMappings": [       //Maps model classes to their data sources. For example, YourDto is mapped to CosmosDB, and if data is not found, it will call the API endpoint GetYourDataAPI.
        {
          "ModelClassName": "YourDto",  // Replace it with your ModelClass Name you want to store in CosmosDB
          "EndpointName": "GetYourDataAPI"  // Replace with your endpoint name for fetching data from API if not found in CosmosDB
        },
        {
          "ModelClassName": "YourSecondDto",  
          "EndpointName": "GetYourSecondDataAPI"  
        }
      ]
    },
    "RedisService": {
      "Configuration": "YourRedisConnectionString",  // Replace with your Redis connection string
      "InstanceName": "YourInstanceName",  // Replace with Redis instance name if required
      "ModalMappings": [           //Maps model classes to their data sources. For example, YourDto is mapped to Redis, and if data is not found, it will call the API endpoint GetYourDataAPI.
        {
          "ModelClassName": "YourDto",  // Replace it with the ModelClass Name you want to store in Redis
          "EndpointName": "GetYourDataAPI"  // Replace with your endpoint name for fetching data from API if not found in CosmosDB
        }
      ]
    },
    "MemoryService": {
      "InstanceName": "YourInstanceName",  // Replace with memory cache instance name if needed
      "ModalMappings": [        //Maps model classes to their data sources. For example, YourDto is mapped to memory cache, and if data is not found, it will call the API endpoint GetYourDataAPI.
        {
          "ModelClassName": "YourDto",  // Replace it with the ModelClass Name you want to store in Memory Cache
          "EndpointName": "GetYourDataAPI"  // Replace with your endpoint name for fetching data from API if not found in CosmosDB
        }
      ]
    },
    "SqlServerService": {
      "ConnectionString": "YourSqlServerConnectionString",  // Replace with your SQL Server connection string
      "TableName": "YourCacheTableName",  // Replace with the SQL Server table name for caching
      "ModalMappings": [       // Maps model classes to SQL Server as the data source, falling back to API if data is not found
        {
          "ModelClassName": "YourSecondDto",  // Replace it with your ModelClass Name you want to store in SQL Server cache
          "EndpointName": "GetYourSecondDataAPI"  // Replace with your endpoint name for fetching data from API if not found in SQL Server
        }
      ]
    },
    "NCacheService": {
      "ServerList": [
        {
          "IPAddress": "xxx.xx.xx.xx",   // Replace it with your NCache server's IP
          "Port": 9800    // Replace it with your NCache server's Port
        }
      ],
      "CacheName": "YourCacheName",  // Replace it with your NCache's Cache Name
      "ModalMappings": [         //Maps model classes to their data sources. For example, YourDto is mapped to NCache, and if data is not found, it will call the API endpoint GetYourDataAPI.
        {
          "ModelClassName": "YourDto",  // Replace it with the ModelClass name you want to store in NCache Server
          "EndpointName": "GetYourDataAPI"  // Replace with your endpoint name for fetching data from API if not found in CosmosDB
        }
      ]
    }
  },
  "CacheSourceSettings": {
    "Endpoints": {
      "GetYourDataAPI": {      //For YourDto
        "BaseUrl": "https://your_api.com",  // Replace with your API's base URL
        "Path": "/api/FetchYourData/{inputParam1}/{inputParam2}",  // Replace with the actual API path; uses placeholders for dynamic input params
        "Method": "GET"  // Set the correct HTTP method for the API request
      },
      "GetYourSecondDataAPI": {      //For YourSecondDto
        "BaseUrl": "https://your_api.com", 
        "Path": "/api/FetchYourSecondData?{inputParam1}&{inputParam2}",  
        "Method": "GET"  
      }
    }
  }
}

ModalMappings: Each model class is mapped to its corresponding cache and fallback API, the package will automatically call the API endpoint as defined in the CacheSourceSettings to fetch the data. For example, YourDto: This class is mapped to the CosmosDB service. If the data is not found in the cache, it will automatically call the GetYourDataAPI to fetch the missing data. It will call below API

https://your_api.com/api/FetchYourData/{inputParam1}/{inputParam2}

YourSecondDto: This class is also managed, but with a different API fallback. It will attempt to retrieve data from the GetYourSecondDataAPI if the data is not found in the cache. Similarly it will call below API

https://your_api.com/api/FetchYourSecondData?{inputParam1}&{inputParam2}

This automatic fallback mechanism ensures that you always have up-to-date data, even if it's not present in the cache.

CacheSourceSettings
  • Endpoints: Defines the API endpoints used to fetch data if it is not found in the cache.
  • BaseUrl: The base URL of the API.
  • Path: The path of the API endpoint, including placeholders for dynamic input parameters. For example, /api/FetchYourData/{inputParam1}/{inputParam2} where {inputParam1} and {inputParam2} are replaced with actual values.
  • Method: The HTTP method to use for the API request (e.g., GET).
Flexible Cache Configuration / Easily Change Cache Server

You can configure your cache service to use either a single cache provider or multiple cache providers based on your requirements: Single Cache Service: If you only need Redis, configure only the RedisService. Multiple Cache Services: If you need Redis and CosmosDB, configure both RedisService and CosmosService in your appsettings.json. Change Cache Server: One of the most powerful features of this package is its flexibility to switch between different cache servers without modifying your C# code. Simply update the configuration in the appsettings.json or any settings file to point to a new cache service (e.g., Redis, CosmosDB, etc.), and the package will handle the switch automatically.

Fallback to API

If the requested data is not found in the configured cache, the package automatically falls back to calling an API to fetch the data. The API endpoint is specified in the appsettings.json under CacheSourceSettings.

For example, with the following configuration:

"Path": "/api/FetchYourData/{inputParam1}/{inputParam2}"
OR
"Path": "/api/FetchYourData?{inputParam1}&{inputParam2}"

And the code:

var yourData = await _cacheSyncMaster.GetRecordAsync<YourDto>(
    "YourCacheKey", 
    new { inputParam1 = "123", inputParam2 = "abc" }
);

The final API call will be made to:

https://your_api.com/api/FetchYourData/123/abc
OR
https://your_api.com/api/FetchYourData?inputParam1=123&inputParam2=abc
Supported Cache Operations

The package supports the following cache operations:

  • Fetch: Retrieve data from the cache or fallback to API if not found.
  • Insert: Add new data to the cache.
  • Update: Modify existing data in the cache.
  • Remove: Delete data from the cache.
Supported Caches
Example
var yourData = await _cacheSyncMaster.GetRecordAsync<YourDto>(
    "YourCacheKey", 
    new { inputParam1 = "123", inputParam2 = "abc" }
);
var result = yourData.Result

await _cacheSyncMaster.CreateOrUpdateRecordAsync<YourDto>("YourCacheKey", data);
await _cacheSyncMaster.RemoveRecordAsync<YourDto>("YourCacheKey");

without Async 

var yourData = await _cacheSyncMaster.GetRecord<YourDto>(
    "YourCacheKey", 
    new { inputParam1 = "123", inputParam2 = "abc" }
);
var result = yourData.Result

await _cacheSyncMaster.CreateOrUpdateRecord<YourDto>("YourCacheKey", data);
await _cacheSyncMaster.RemoveRecord<YourDto>("YourCacheKey");
Fetching Data from Cache

1. Retrieving Data: The first step is fetching data from the cache using vTCacheSyncMaster. You use the GetRecordAsync<YourDto> or GetRecord<YourDto> method, passing the following parameters: "YourCacheKey": This is the cache key that uniquely identifies the data you want to retrieve from the cache. { inputParam1 = "123", inputParam2 = "abc" }: These parameters are for fallback to API as mentioned above. The result is awaited, and the retrieved data is stored in the yourData variable.

2. Extracting the Result: Once the cache returns a result, the next step is to extract the actual data: The Result property of the yourData object contains the cached data, which in this case is of type YourDto.

Creating or Updating a Cache Record: 

To ensure the cache has the most up-to-date data, you can create or update a cache record: The CreateOrUpdateRecordAsync<YourDto> or CreateOrUpdateRecord<YourDto> method is used with the cache key "YourCacheKey" and the yourDataobject. This will update the cache entry associated with the given key, ensuring it contains the latest data.

Removing a Cache Record

To remove outdated or unnecessary data from the cache: The RemoveRecordAsync<YourDto> or RemoveRecord<YourDto> method is called with the cache key "YourCacheKey". This effectively deletes the cache entry associated with that key, ensuring the cache no longer holds that specific data.

Conclusion

vTCacheSyncMaster is your all-in-one solution for seamless caching management. It not only supports multiple cache providers but also optimizes your code for better performance, flexibility, and maintainability. Install it today and see the difference! This version incorporates the added explanation regarding how specific DTOs like YourDto and YourSecondDto will call different API endpoints for their data when the cache is not found. Let me know if you'd like any further changes!

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.1 103 9/10/2024