### DefaultKeyTransformer Usage Example Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/serialization.md Example of using the DefaultKeyTransformer. The key is stored exactly as provided. ```csharp client.Set("user-123", user, 300); // Stored as "user-123" ``` -------------------------------- ### Usage Examples for AddEnyimMemcached Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/memcached-configuration.md Demonstrates various ways to register Enyim Memcached using different configuration sources and methods. ```csharp services.AddEnyimMemcached(); ``` ```csharp services.AddEnyimMemcached("enyimMemcached"); ``` ```csharp services.AddEnyimMemcached(configuration, "enyimMemcached"); ``` ```csharp services.AddEnyimMemcached(configuration.GetSection("enyimMemcached")); ``` -------------------------------- ### Minimal EnyimMemcached Configuration Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/configuration.md Use this for basic setup, relying on default settings or a custom section in appsettings.json. ```csharp services.AddEnyimMemcached(); ``` ```csharp services.AddEnyimMemcached("cacheSettings"); ``` -------------------------------- ### IDistributedCache Implementation Example Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/COMPLETION-SUMMARY.txt Shows a basic usage of the IDistributedCache interface, demonstrating how to set and get items from the cache. This is useful for integrating Memcached with ASP.NET Core's distributed caching abstraction. ```csharp public class MyCacheService { private readonly IDistributedCache _cache; public MyCacheService(IDistributedCache cache) { _cache = cache; } public async Task SetValueAsync(string key, string value) { await _cache.SetStringAsync(key, value, new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5) }); } public async Task GetValueAsync(string key) { return await _cache.GetStringAsync(key); } } ``` -------------------------------- ### Basic Key-Value Operations with IMemcachedClient Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/COMPLETION-SUMMARY.txt Provides fundamental examples of setting, getting, and removing items from the cache using the IMemcachedClient interface. These are the most common operations for interacting with Memcached. ```csharp var success = await _client.SetAsync("myKey", "myValue"); var value = await _client.GetAsync("myKey"); await _client.RemoveAsync("myKey"); ``` -------------------------------- ### Warming Cache on Startup with Hosted Service Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/distributed-cache.md Illustrates how to pre-populate the distributed cache with essential data, like application configuration, when the application starts. ```csharp public class CacheWarmupHostedService : IHostedService { private readonly IDistributedCache _cache; private readonly IConfiguration _configuration; public async Task StartAsync(CancellationToken cancellationToken) { // Load common data on startup var options = new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1) }; var config = _configuration.Get(); var json = JsonSerializer.Serialize(config); await _cache.SetStringAsync("app-config", json, options, cancellationToken); } public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; } ``` -------------------------------- ### Development Configuration Example Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/configuration.md This JSON configuration is suitable for development environments. It specifies the protocol, server addresses, and socket pool settings. ```json { "enyimMemcached": { "Protocol": "Text", "Servers": [ { "Address": "localhost", "Port": 11211 } ], "SuppressException": false, "SocketPool": { "MinPoolSize": 1, "MaxPoolSize": 5, "ConnectionTimeout": "00:00:05", "ReceiveTimeout": "00:00:05" } } } ``` -------------------------------- ### JSON Configuration Example Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/COMPLETION-SUMMARY.txt Illustrates how to configure the Memcached client using a JSON configuration file. This approach is often used for managing settings in production environments. ```json { "Enyim.Memcached.dll": { "servers": [ "127.0.0.1:11211", "192.168.1.100:11211" ], "protocol": "Text", "socketPool": { "minPoolSize": 5, "maxPoolSize": 20, "connectionTimeout": "00:00:05", "receiveTimeout": "00:00:05" } } } ``` -------------------------------- ### MemcachedClient Add Usage Example Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/memcached-client.md Demonstrates how to use the Add and AddAsync methods to store an object in the cache. Handles cases where the item may already exist. ```csharp var client = serviceProvider.GetRequiredService(); bool added = client.Add("user-123", userObject, 3600); if (!added) { // Item already exists in cache } // Async version bool addedAsync = await client.AddAsync("user-123", userObject, 3600); ``` -------------------------------- ### Configuration Classes Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/DOCUMENTATION-INDEX.md Configuration classes allow for detailed setup of the Memcached client and its associated components, including connection pooling, server addresses, and authentication. ```APIDOC ## Configuration Classes ### MemcachedClientOptions - **Properties**: 9 properties documented. - **Methods**: 2 methods documented. ### SocketPoolOptions - **Properties**: 8 properties documented. - **Methods**: 2 methods documented. ### Server - **Properties**: 2 properties documented. ### Authentication - **Properties**: 2 properties documented. ### IMemcachedClientConfiguration Interface - Fully documented. ``` -------------------------------- ### Set and Get with Simple API Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/README.md Use the Simple API for basic cache operations where boolean success is sufficient and exceptions are suppressed by default. ```csharp bool success = await _cache.SetAsync("key", value, 300); var user = await _cache.GetValueAsync("user-123"); ``` -------------------------------- ### Configure Memcached Client Programmatically Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/memcached-configuration.md Example of configuring memcached client options programmatically, including server details, protocol, socket pool settings, and authentication. ```csharp services.AddEnyimMemcached(options => { options.AddServer("memcached", 11211); options.Protocol = MemcachedProtocol.Binary; options.SocketPool.MinPoolSize = 5; options.SocketPool.MaxPoolSize = 100; options.AddPlainTextAuthenticator("", "user", "pass"); }); ``` -------------------------------- ### Use IMemcachedClient for Caching Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/README.md Demonstrates using the IMemcachedClient interface to retrieve or create cached data. This example fetches blog posts, caching them for a specified duration. ```csharp public class HomeController : Controller { private readonly IMemcachedClient _memcachedClient; private readonly IBlogPostService _blogPostService; public HomeController(IMemcachedClient memcachedClient, IBlogPostService blogPostService) { _memcachedClient = memcachedClient; _blogPostService = blogPostService; } public async Task Index() { var cacheKey = "blogposts-recent"; var cacheSeconds = 600; var posts = await _memcachedClient.GetValueOrCreateAsync( cacheKey, cacheSeconds, async () => await _blogPostService.GetRecent(10)); return Ok(posts); } } ``` -------------------------------- ### C# MessagePack Transcoder Setup Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/serialization.md Configure EnyimMemcachedCore to use MessagePack for serialization in C#. This is recommended for cross-language compatibility and performance. ```csharp public class User { public int Id { get; set; } public string Name { get; set; } } services.AddEnyimMemcached(options => { options.Transcoder = typeof(MessagePackTranscoder).FullName; }); // Java code can also use MessagePack library to deserialize ``` -------------------------------- ### Memcached Configuration JSON Example Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/memcached-configuration.md Standard appsettings.json configuration for the Enyim Memcached client. This JSON defines servers, authentication, and socket pool settings. ```json { "enyimMemcached": { "Protocol": "Binary", "Servers": [ { "Address": "memcached1", "Port": 11211 }, { "Address": "memcached2", "Port": 11211 } ], "KeyTransformer": "Enyim.Caching.Memcached.KeyTransformers.DefaultKeyTransformer", "Transcoder": "Enyim.Caching.Memcached.Transcoders.DefaultTranscoder", "UseSslStream": false, "UseIPv6": false, "SuppressException": true, "SocketPool": { "MinPoolSize": 5, "MaxPoolSize": 100, "ConnectionTimeout": "00:00:10", "ReceiveTimeout": "00:00:10", "DeadTimeout": "00:00:10", "QueueTimeout": "00:00:00.1000000", "ConnectionIdleTimeout": "00:00:00", "InitPoolTimeout": "00:01:00" }, "Authentication": { "Type": "Enyim.Caching.Memcached.PlainTextAuthenticator", "Parameters": { "zone": "", "userName": "username", "password": "password" } } } } ``` -------------------------------- ### Serialization and Transcoding Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/COMPLETION-SUMMARY.txt Documentation for the ITranscoder interface and available transcoders, along with IMemcachedKeyTransformer for key transformations and examples for custom implementations. ```APIDOC ## Serialization (Transcoding) ### Description Covers the mechanisms for serializing and deserializing objects to and from the Memcached protocol, including custom transcoder implementations. ### Interface `ITranscoder` ### Key Transformer Interface `IMemcachedKeyTransformer` ### Transcoder and Key Transformer Details (Documentation for all transcoders, key transformers, use cases, custom examples, and performance comparisons can be found in `api-reference/serialization.md`) ``` -------------------------------- ### Configure EnyimMemcached for Production (Compatibility) Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/README.md This production configuration prioritizes compatibility by using the binary protocol and specifying multiple cache servers. It's a simpler setup compared to the high-performance variant. ```csharp services.AddEnyimMemcached(options => { options.Protocol = MemcachedProtocol.Binary; options.AddServer("cache1.prod", 11211); options.AddServer("cache2.prod", 11211); }); ``` -------------------------------- ### Basic EnyimMemcached Usage Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/README.md Inject IMemcachedClient to perform basic cache operations like getting and setting user data. ```csharp public class MyService { private readonly IMemcachedClient _cache; public MyService(IMemcachedClient cache) { _cache = cache; } public async Task GetUserAsync(int userId) { return await _cache.GetValueAsync($"user-{userId}"); } public async Task UpdateUserAsync(User user) { await _cache.SetAsync($"user-{user.Id}", user, TimeSpan.FromHours(1)); } } ``` -------------------------------- ### Implement Custom Key Transformer Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/serialization.md Implement the IMemcachedKeyTransformer interface to define custom logic for transforming cache keys. This example adds a fixed prefix to all keys. ```csharp using Enyim.Caching.Memcached; public class PrefixedKeyTransformer : IMemcachedKeyTransformer { private readonly string _prefix; public PrefixedKeyTransformer(string prefix = "app:") { _prefix = prefix; } public string Transform(string key) { if (string.IsNullOrEmpty(key)) throw new ArgumentNullException(nameof(key)); // Add prefix to all keys return _prefix + key; } } ``` -------------------------------- ### Example Custom Flags Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/serialization.md Define constants for custom flags to indicate specific properties of cached data, such as format, compression, or encryption. ```csharp const uint JsonFormat = 1; const uint CompressedFlag = 0x100; const uint EncryptedFlag = 0x200; ``` -------------------------------- ### SHA1KeyTransformer Configuration and Usage Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/serialization.md Configuration and usage example for SHA1KeyTransformer. This transformer hashes keys using SHA1, producing a fixed 40-byte output, suitable for long or arbitrary length keys. ```csharp services.AddEnyimMemcached(options => { options.KeyTransformer = typeof(SHA1KeyTransformer).FullName; options.AddServer("localhost", 11211); }); // Arbitrary length key string longKey = "user:profile:detailed:information:" + userId; client.Set(longKey, profile, 3600); // Automatically hashed to 40 bytes ``` -------------------------------- ### MemcachedClient Class Reference Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/DOCUMENTATION-INDEX.md Reference for the MemcachedClient class, including its constructors, properties, and core operations like Add, Set, Get, and Remove. ```APIDOC ## MemcachedClient Operations ### Description Provides methods for interacting with a Memcached server, including basic cache operations, retrieval with CAS, and server statistics. ### Methods - **Add**: Adds an item to the cache if it does not already exist. - **Set**: Adds or replaces an item in the cache. - **Replace**: Replaces an existing item in the cache. - **Get**: Retrieves a single item from the cache. - **Get(keys)**: Retrieves multiple items from the cache. - **GetValueAsync**: Asynchronously retrieves a single item. - **GetValueOrCreateAsync**: Asynchronously retrieves an item or creates it if it doesn't exist. - **TryGet**: Attempts to retrieve an item from the cache. - **Append**: Appends data to an existing item. - **Prepend**: Prepends data to an existing item. - **Store**: Stores an item with specific options. - **Cas**: Stores an item only if its current CAS value matches the provided one. - **Increment**: Atomically increments the value of an item. - **Decrement**: Atomically decrements the value of an item. - **Touch**: Updates the expiration time of an item. - **Remove**: Removes an item from the cache. - **FlushAll**: Removes all items from all servers. - **Stats**: Retrieves statistics from the Memcached servers. ### Interfaces Implemented - **IMemcachedResultsClient**: For operations returning detailed results. - **IDistributedCache**: For integration with ASP.NET Core's distributed caching abstraction. ``` -------------------------------- ### Implement Custom JSON Transcoder Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/serialization.md Implement the ITranscoder interface to handle custom serialization, such as JSON. This example shows how to serialize and deserialize objects using System.Text.Json. ```csharp using Enyim.Caching.Memcached; using System.Text.Json; using System.Text; public class JsonTranscoder : ITranscoder { private readonly JsonSerializerOptions _options; public JsonTranscoder() { _options = new JsonSerializerOptions(); } public CacheItem Serialize(object value) { if (value == null) { return new CacheItem(0, new ArraySegment(Array.Empty())); } var json = JsonSerializer.Serialize(value); var bytes = Encoding.UTF8.GetBytes(json); const uint jsonFlag = 1; // Custom flag for JSON return new CacheItem(jsonFlag, new ArraySegment(bytes)); } public object Deserialize(CacheItem item) { if (item.Data.Count == 0) return null; var json = Encoding.UTF8.GetString(item.Data.Array, item.Data.Offset, item.Data.Count); return JsonSerializer.Deserialize(json, _options); } public T Deserialize(CacheItem item) { if (item.Data.Count == 0) return default; var json = Encoding.UTF8.GetString(item.Data.Array, item.Data.Offset, item.Data.Count); return JsonSerializer.Deserialize(json, _options); } } ``` -------------------------------- ### IMemcachedClient Reference Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/COMPLETION-SUMMARY.txt Detailed documentation for the IMemcachedClient interface, including constructors, properties, method overloads, parameter and return types, and usage examples. It also covers the IDistributedCache implementation and thread safety considerations. ```APIDOC ## IMemcachedClient ### Description Provides the core interface for interacting with a Memcached server, including methods for basic cache operations, retrieval, and management. ### Interface `IMemcachedClient` ### Methods (Documentation for all method overloads, parameters, return types, and examples can be found in `api-reference/memcached-client.md`) ### Properties (Documentation for all properties can be found in `api-reference/memcached-client.md`) ### Events (Documentation for all events can be found in `api-reference/memcached-client.md`) ### IDistributedCache Implementation (Details on how `IMemcachedClient` implements `IDistributedCache` can be found in `api-reference/memcached-client.md` and `api-reference/distributed-cache.md`) ``` -------------------------------- ### Use IDistributedCache for Caching Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/README.md Shows how to use the IDistributedCache interface, compatible with ASP.NET Core's caching abstractions, to store and retrieve data. This example caches creative DTOs. ```csharp public class CreativeService { private ICreativeRepository _creativeRepository; private IDistributedCache _cache; public CreativeService( ICreativeRepository creativeRepository, IDistributedCache cache) { _creativeRepository = creativeRepository; _cache = cache; } public async Task> GetCreatives(string unitName) { var cacheKey = $"creatives_{unitName}"; IList creatives = null; var creativesJson = await _cache.GetStringAsync(cacheKey); if (creativesJson == null) { creatives = await _creativeRepository.GetCreatives(unitName) .ProjectTo().ToListAsync(); var json = string.Empty; if (creatives != null && creatives.Count() > 0) { json = JsonConvert.SerializeObject(creatives); } await _cache.SetStringAsync( cacheKey, json, new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(5))); } else { creatives = JsonConvert.DeserializeObject>(creativesJson); } return creatives; } } ``` -------------------------------- ### ServerStats Class Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/types.md Provides methods to retrieve statistics for Memcached servers. Use this class to get aggregate statistics across all servers or specific details like version and uptime for individual servers. ```csharp namespace Enyim.Caching.Memcached { public sealed class ServerStats { public static readonly IPEndPoint All public long GetValue(EndPoint server, StatItem item) public Version GetVersion(EndPoint server) public TimeSpan GetUptime(EndPoint server) public string GetRaw(EndPoint server, string key) public string GetRaw(EndPoint server, StatItem item) public IEnumerable> GetRaw(string key) } } ``` -------------------------------- ### Configure SHA1 Key Transformer for Long Keys Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/configuration.md Use the SHA1 key transformer when keys might exceed memcached's 250-byte limit. This example manually sets the transformer and adds a server. ```csharp services.AddEnyimMemcached(options => { options.KeyTransformer = typeof(SHA1KeyTransformer).FullName; options.AddServer("localhost", 11211); }); ``` -------------------------------- ### Configure Services in Startup.cs Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/README.md Add the Enyim Memcached client services to the dependency injection container in your application's Startup.cs file. Several overloads are available for different configuration needs. ```csharp public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddEnyimMemcached(); // services.AddEnyimMemcached("enyimMemcached"); // services.AddEnyimMemcached(Configuration); // services.AddEnyimMemcached(Configuration, "enyimMemcached"); // services.AddEnyimMemcached(Configuration.GetSection("enyimMemcached")); // services.AddEnyimMemcached(options => options.AddServer("memcached", 11211)); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseEnyimMemcached(); } } ``` -------------------------------- ### Manually Configure Server from Environment Variables Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/configuration.md Manually configure the EnyimMemcached server using environment variables for host and port. ```csharp services.AddEnyimMemcached(options => { var server = Environment.GetEnvironmentVariable("MEMCACHED_HOST") ?? "localhost"; var port = int.Parse(Environment.GetEnvironmentVariable("MEMCACHED_PORT") ?? "11211"); options.AddServer(server, port); }); ``` -------------------------------- ### Get Cached Data (Synchronous) Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/distributed-cache.md Retrieve cached data as bytes using the synchronous Get method. Returns null if the key is not found. Automatically refreshes sliding expiration if set. ```csharp byte[] cachedBytes = _cache.Get($"user-{userId}"); if (cachedBytes != null) { var json = Encoding.UTF8.GetString(cachedBytes); var user = JsonSerializer.Deserialize(json); return user; } return null; ``` -------------------------------- ### Get Operations Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/advanced-operations.md Execute detailed 'Get' operations to retrieve cached items with comprehensive result information, including success status, value presence, and CAS tokens. Supports retrieving single items, multiple items by keys, and 'try-get' operations with output parameters. ```APIDOC ## Get Operations ### ExecuteGet #### Description Retrieves a single item from the cache with detailed result information. #### Signature `IGetOperationResult ExecuteGet(string key)` ### ExecuteGet (Multiple Keys) #### Description Retrieves multiple items from the cache by their keys, returning a dictionary of results. #### Signature `IDictionary ExecuteGet(IEnumerable keys)` ### ExecuteTryGet #### Description Attempts to retrieve an item from the cache, returning a detailed result and the value via an output parameter. #### Signature `IGetOperationResult ExecuteTryGet(string key, out object value)` ### ExecuteTryGet #### Description Attempts to retrieve a typed item from the cache, returning a detailed result and the value via an output parameter. #### Signature `IGetOperationResult ExecuteTryGet(string key, out T value)` ### Usage Example (Single Get) ```csharp var result = client.ExecuteGet("user-123"); if (result.Success && result.HasValue) { var user = result.Value; var cas = result.Cas; // For CAS operations Console.WriteLine($"User: {user.Name}"); } else { Console.WriteLine($"Failed: {result.Message}"); } ``` ### Usage Example (Multiple Keys) ```csharp var keys = new[] { "user-1", "user-2", "user-3" }; var results = client.ExecuteGet(keys); foreach (var kvp in results) { var key = kvp.Key; var result = kvp.Value; if (result.Success && result.HasValue) { Console.WriteLine($"{key}: Found"); } } ``` ``` -------------------------------- ### CAS Operations (Compare-And-Swap) Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/advanced-operations.md Detailed workflow and example for using Compare-And-Swap for optimistic locking. ```APIDOC ## CAS Operations in Detail ### Description Compare-And-Swap (CAS) is an optimistic locking mechanism used to ensure data consistency when multiple processes might be updating the same item concurrently. It involves retrieving an item along with its CAS token, modifying the item locally, and then attempting to store the modified item only if the CAS token matches the current token on the server. If the token does not match, it indicates that the item has been modified by another process since it was retrieved, and the operation fails, requiring a retry. ### Workflow Example ```csharp // Scenario: Multiple processes updating same user public async Task UpdateUserWithRetryAsync(int userId, Action updateFn) { int maxRetries = 3; for (int i = 0; i < maxRetries; i++) { // 1. Get current value with CAS token var casResult = client.GetWithCas($"user-{userId}"); if (!casResult.HasValue) { // Item doesn't exist return false; } var user = casResult.Value; var cas = casResult.Cas; // 2. Modify locally updateFn(user); // 3. Attempt atomic update var storeResult = client.Cas(StoreMode.Set, $"user-{userId}", user, cas); if (storeResult.Success) { // Success! We had the right version return true; } // CAS failed - someone else changed it // Retry from step 1 await Task.Delay(100); // Brief delay } throw new ConcurrencyException("Failed to update after retries"); } ``` ### Key Steps: 1. **Get with CAS**: Retrieve the item and its associated CAS token using `GetWithCas`. 2. **Modify Locally**: Apply desired changes to the retrieved item. 3. **Attempt Atomic Update**: Use the `Cas` method with the original CAS token to attempt an update. If the token matches, the update succeeds; otherwise, it fails, indicating a conflict. ``` -------------------------------- ### Basic Memcached Client Configuration Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/COMPLETION-SUMMARY.txt Demonstrates programmatic configuration of the Memcached client using MemcachedClientOptions. This is useful for setting up the client in code, especially when default configurations are not sufficient. ```csharp var configuration = new MemcachedClientOptions { Servers = new List { "127.0.0.1:11211" }, Protocol = Protocol.Text, SocketPool = new SocketPoolOptions { MinPoolSize = 5, MaxPoolSize = 20, ConnectionTimeout = TimeSpan.FromSeconds(5), ReceiveTimeout = TimeSpan.FromSeconds(5) } }; var client = new MemcachedClient(configuration); ``` -------------------------------- ### Set and Get with IDistributedCache API Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/README.md Utilize the standard .NET IDistributedCache interface for common caching operations. ```csharp await _cache.SetStringAsync("key", json, options); var value = await _cache.GetStringAsync("key"); ``` -------------------------------- ### IGetOperationResult Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/advanced-operations.md Represents the result of a get operation, including the retrieved typed value and a CAS token for optimistic concurrency. ```APIDOC ## IGetOperationResult ### Description Result with typed value and CAS token. ### Properties - **Value** (T) - Retrieved value - **HasValue** (bool) - Whether value exists - **Cas** (ulong) - Compare-and-swap token - **Success** (bool) - Operation success ``` -------------------------------- ### Get Operations Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/memcached-client.md Retrieves single or multiple items from the cache with optional type conversion. Supports both synchronous and asynchronous operations. ```APIDOC ## Get(string key) ### Description Retrieves a single item from the cache. ### Method `Get` ### Parameters #### Path Parameters - **key** (string) - Required - Cache key to retrieve ### Returns - `T` - The deserialized value, or `null` if not found ### Request Example ```csharp var user = client.Get("user-123"); if (user != null) { // Process user } ``` ``` ```APIDOC ## Get(IEnumerable keys) ### Description Retrieves multiple items from the cache. ### Method `Get` ### Parameters #### Path Parameters - **keys** (IEnumerable) - Required - Collection of cache keys to retrieve ### Returns - `IDictionary` - Dictionary mapping keys to values ### Request Example ```csharp var keys = new[] { "user-1", "user-2", "user-3" }; var users = client.Get(keys); foreach (var kvp in users) { Console.WriteLine($"{kvp.Key}: {kvp.Value.Name}"); } ``` ``` ```APIDOC ## GetAsync(string key) ### Description Asynchronously retrieves a single item from the cache. ### Method `GetAsync` ### Parameters #### Path Parameters - **key** (string) - Required - Cache key to retrieve ### Returns - `Task>` - A task that represents the asynchronous operation, yielding the deserialized value or null. ### Request Example ```csharp var userAsync = await client.GetAsync("user-123"); ``` ``` ```APIDOC ## GetAsync(IEnumerable keys) ### Description Asynchronously retrieves multiple items from the cache. ### Method `GetAsync` ### Parameters #### Path Parameters - **keys** (IEnumerable) - Required - Collection of cache keys to retrieve ### Returns - `Task>` - A task that represents the asynchronous operation, yielding a dictionary mapping keys to values. ### Request Example ```csharp var keys = new[] { "user-1", "user-2", "user-3" }; var usersAsync = await client.GetAsync(keys); ``` ``` -------------------------------- ### Add Enyim Memcached with IConfigurationSection Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/memcached-configuration.md Loads configuration directly from a provided `IConfigurationSection`. This allows for more flexible configuration management. ```csharp IServiceCollection AddEnyimMemcached( this IServiceCollection services, IConfigurationSection configurationSection, bool asDistributedCache = false) ``` -------------------------------- ### Load Configuration from Environment Variables Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/configuration.md Use ConfigurationBuilder to load settings from appsettings.json and environment variables prefixed with ENYIMMEMCACHED__. ```csharp var configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .AddEnvironmentVariables() // Loads ENYIMMEMCACHED__* vars .Build(); services.AddEnyimMemcached(configuration, "enyimMemcached"); ``` -------------------------------- ### Configure Binary Protocol Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/configuration.md Set the protocol to Binary for improved efficiency and feature support. Requires memcached server support. ```json { "enyimMemcached": { "Protocol": "Binary" } } ``` -------------------------------- ### Define IGetOperationResult Interface Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/advanced-operations.md Represents the result of a get operation, including the retrieved typed value and a CAS token for optimistic concurrency. ```csharp public interface IGetOperationResult : INullableOperationResult, ICasOperationResult { } ``` -------------------------------- ### Configure appsettings.json with Authentication Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/README.md Configure appsettings.json with authentication details, including the authenticator type and parameters like username and password. ```json { "enyimMemcached": { "Servers": [ { "Address": "memcached", "Port": 11211 } ], "Authentication": { "Type": "Enyim.Caching.Memcached.PlainTextAuthenticator", "Parameters": { "zone": "", "userName": "username", "password": "password" } } } } ``` -------------------------------- ### Adjust Timeout Settings Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/errors.md Modify connection, receive, queue, and initial pool setup timeouts to prevent or resolve timeout errors. ```csharp options.SocketPool.ConnectionTimeout = TimeSpan.FromSeconds(15); // Increase options.SocketPool.ReceiveTimeout = TimeSpan.FromSeconds(15); options.SocketPool.QueueTimeout = TimeSpan.FromMilliseconds(500); // Wait longer for pool options.SocketPool.InitPoolTimeout = TimeSpan.FromSeconds(90); // Initial setup ``` -------------------------------- ### IDistributedCache Interface Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/COMPLETION-SUMMARY.txt Reference for the IDistributedCache interface, detailing its methods for distributed caching, including entry options, expiration behavior, and usage examples. ```APIDOC ## IDistributedCache ### Description Interface for implementing distributed caching functionalities, compatible with ASP.NET Core's caching abstractions. ### Interface `IDistributedCache` ### Methods (All methods of the `IDistributedCache` interface are documented in `api-reference/distributed-cache.md`) ### DistributedCacheEntryOptions (Details on `DistributedCacheEntryOptions`, including expiration settings (absolute, sliding, combined), can be found in `api-reference/distributed-cache.md`) ### Usage Examples (Examples demonstrating the usage of `IDistributedCache` can be found in `api-reference/distributed-cache.md`) ``` -------------------------------- ### MemcachedClientOptions and Configuration Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/DOCUMENTATION-INDEX.md Details on configuring the Memcached client, including options for the client, socket pool, servers, and authentication. ```APIDOC ## Memcached Client Configuration ### Description This section details the configuration options available for the Enyim Memcached client, covering client-specific settings, socket pool tuning, server definitions, and authentication mechanisms. ### Configuration Classes - **MemcachedClientOptions**: Main configuration class for the client. - **SocketPoolOptions**: Options for tuning the socket pool behavior. - **Server**: Represents a single Memcached server endpoint. - **Authentication**: Configuration for authentication credentials. ### Configuration Formats - **appsettings.json**: Examples for minimal, standard, and complete JSON configurations. - **Programmatic Configuration**: Examples of configuring the client using C# code. ### Key Configuration Areas - **Protocol Selection**: Choosing the Memcached protocol. - **Key Transformer**: Options for transforming cache keys. - **Transcoder**: Settings for serializing and deserializing cache items. - **Socket Pool Tuning**: Parameters like minimum/maximum connections, queue timeouts. - **Authentication**: Configuring authentication methods and credentials. - **Error Handling**: Strategies for handling connection and operation errors. - **Validation Rules**: Rules applied to configuration settings. ``` -------------------------------- ### Get String from Cache (Asynchronous) Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/distributed-cache.md Convenience method to asynchronously retrieve a UTF-8 decoded string from the cache. Returns null if the key is not found. ```csharp string cachedJson = await _cache.GetStringAsync("config-key"); if (!string.IsNullOrEmpty(cachedJson)) { var config = JsonSerializer.Deserialize(cachedJson); } ``` -------------------------------- ### Get String from Cache (Synchronous) Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/distributed-cache.md Convenience method to synchronously retrieve a UTF-8 decoded string from the cache. Returns null if the key is not found. ```csharp string cachedJson = _cache.GetString("config-key"); if (cachedJson != null) { var config = JsonSerializer.Deserialize(cachedJson); } ``` -------------------------------- ### AddEnyimMemcached with setupAction Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/memcached-configuration.md Registers the memcached client by configuring options via an action delegate. Optionally registers as an IDistributedCache. ```APIDOC ## AddEnyimMemcached (setupAction) ### Description Registers the memcached client by configuring options via an action delegate. Optionally registers as an IDistributedCache. ### Method Signature ```csharp IServiceCollection AddEnyimMemcached( this IServiceCollection services, Action setupAction, bool asDistributedCache = false) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Description | |---|---|---|---| | services | IServiceCollection | Yes | DI service collection | | setupAction | Action | No | Configuration action | | asDistributedCache | bool | No | Register as IDistributedCache (default: false) | ### Request Example ```csharp services.AddEnyimMemcached(options => { options.AddServer("memcached", 11211); options.Protocol = MemcachedProtocol.Binary; options.SocketPool.MinPoolSize = 5; options.SocketPool.MaxPoolSize = 100; options.AddPlainTextAuthenticator("", "user", "pass"); }); // Registering as IDistributedCache programmatically services.AddEnyimMemcached(options => { /* configuration */ }, asDistributedCache: true); ``` ### Response #### Success Response `IServiceCollection` for chaining. ``` -------------------------------- ### AddServer Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/memcached-configuration.md Adds a memcached server to the configuration. ```APIDOC ## AddServer Adds a memcached server to the configuration. ### Method Signature ```csharp void AddServer(string address, int port) ``` ### Parameters #### Path Parameters - **address** (string) - Required - Server hostname or IP address - **port** (int) - Required - Server port (default: 11211) ### Usage Example ```csharp var options = new MemcachedClientOptions(); options.AddServer("memcached1", 11211); options.AddServer("memcached2", 11211); options.AddServer("localhost", 11211); ``` ``` -------------------------------- ### Development Environment Configuration Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/serialization.md Configure Enyim Memcached for a development environment using the text protocol, default transcoder, and default key transformer. Connect to a local Memcached instance. ```csharp services.AddEnyimMemcached(options => { options.Protocol = MemcachedProtocol.Text; options.Transcoder = typeof(DefaultTranscoder).FullName; options.KeyTransformer = typeof(DefaultKeyTransformer).FullName; options.AddServer("localhost", 11211); }); ``` -------------------------------- ### Basic Caching Pattern with IDistributedCache Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/distributed-cache.md Demonstrates a common pattern for retrieving data from a cache or, if not found, fetching it from a repository and storing it in the cache. ```csharp public class UserService { private readonly IDistributedCache _cache; private readonly IUserRepository _repository; public UserService(IDistributedCache cache, IUserRepository repository) { _cache = cache; _repository = repository; } public async Task GetUserAsync(int userId) { string cacheKey = $"user-{userId}"; // Try cache string cachedJson = await _cache.GetStringAsync(cacheKey); if (!string.IsNullOrEmpty(cachedJson)) { return JsonSerializer.Deserialize(cachedJson); } // Get from database var user = await _repository.GetUserByIdAsync(userId); if (user != null) { // Store in cache var options = new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1) }; var json = JsonSerializer.Serialize(user); await _cache.SetStringAsync(cacheKey, json, options); } return user; } } ``` -------------------------------- ### Action-Based EnyimMemcached Configuration Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/configuration.md Configure specific options like servers and protocol using a lambda expression. ```csharp services.AddEnyimMemcached(options => { options.AddServer("localhost", 11211); options.Protocol = MemcachedProtocol.Binary; }); ``` -------------------------------- ### MemcachedClient Constructor Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/memcached-client.md Initializes a new instance of the MemcachedClient class. ```APIDOC ## Constructor ### Signature ```csharp MemcachedClient(ILoggerFactory loggerFactory, IMemcachedClientConfiguration configuration) ``` ### Parameters #### Path Parameters - **loggerFactory** (ILoggerFactory) - Required - Factory for creating loggers - **configuration** (IMemcachedClientConfiguration) - Required - Configuration for the client, including server endpoints, socket pool settings, authentication, transcoders ``` -------------------------------- ### MemcachedClient Constructor Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/memcached-client.md Initializes a new instance of the MemcachedClient class. Requires a logger factory and client configuration. ```csharp MemcachedClient(ILoggerFactory loggerFactory, IMemcachedClientConfiguration configuration) ``` -------------------------------- ### Minimal EnyimMemcached Configuration Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/README.md Configure EnyimMemcached by specifying server addresses and ports in appsettings.json and registering the service in Program.cs/Startup.cs. ```json { "enyimMemcached": { "Servers": [ { "Address": "localhost", "Port": 11211 } ] } } ``` -------------------------------- ### AddDefaultServer Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/memcached-configuration.md Adds the default server (memcached:11211). ```APIDOC ## AddDefaultServer Adds the default server (memcached:11211). ### Method Signature ```csharp void AddDefaultServer() ``` ``` -------------------------------- ### Get Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/distributed-cache.md Retrieves a cached item as bytes from the distributed cache using a specified key. Returns null if the item is not found. Automatically refreshes sliding expiration if configured. ```APIDOC ## Get ### Description Retrieves a cached item as bytes. ### Method `byte[] Get(string key)` ### Parameters #### Path Parameters - **key** (string) - Required - Cache key to retrieve ### Returns - **byte[]** - Cached bytes, or `null` if not found ### Remarks Automatically refreshes sliding expiration if set. ### Usage Example ```csharp private readonly IDistributedCache _cache; public void GetCachedData(string userId) { byte[] cachedBytes = _cache.Get($"user-{userId}"); if (cachedBytes != null) { var json = Encoding.UTF8.GetString(cachedBytes); var user = JsonSerializer.Deserialize(json); return user; } return null; } ``` ``` -------------------------------- ### Production - Compatibility Configuration Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/serialization.md Configure Enyim Memcached for production with compatibility in mind, using the binary protocol, default transcoder, and Base64 key transformer. Connect to multiple cache servers. ```csharp services.AddEnyimMemcached(options => { options.Protocol = MemcachedProtocol.Binary; options.Transcoder = typeof(DefaultTranscoder).FullName; options.KeyTransformer = typeof(Base64KeyTransformer).FullName; options.AddServer("cache1", 11211); options.AddServer("cache2", 11211); }); ``` -------------------------------- ### SASL PLAIN Authentication JSON Configuration Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/configuration.md Example JSON structure for configuring SASL PLAIN authentication, specifying the authenticator type and parameters including zone, username, and password. ```json { "Authentication": { "Type": "Enyim.Caching.Memcached.PlainTextAuthenticator", "Parameters": { "zone": "", "userName": "cache_user", "password": "secure_password" } } } ``` -------------------------------- ### Retrieve Server Statistics Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/memcached-client.md Retrieves statistics from memcached servers. You can fetch general statistics or specific types. The returned object provides methods to get server version and uptime. ```csharp var stats = client.Stats(); ``` ```csharp var version = stats.GetVersion(stats.ServerStats.All); ``` ```csharp var uptime = stats.GetUptime(someServerEndpoint); ``` -------------------------------- ### Standard EnyimMemcached Configuration Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/configuration.md Configure common options like protocol, multiple servers, key transformer, transcoder, and socket pool settings. Adjust 'Protocol' and server details as needed. ```json { "enyimMemcached": { "Protocol": "Binary", "Servers": [ { "Address": "memcached1", "Port": 11211 }, { "Address": "memcached2", "Port": 11211 } ], "KeyTransformer": "Enyim.Caching.Memcached.KeyTransformers.DefaultKeyTransformer", "Transcoder": "Enyim.Caching.Memcached.Transcoders.DefaultTranscoder", "UseSslStream": false, "UseIPv6": false, "SuppressException": true, "SocketPool": { "MinPoolSize": 5, "MaxPoolSize": 100, "ConnectionTimeout": "00:00:10", "ReceiveTimeout": "00:00:10", "DeadTimeout": "00:00:10", "QueueTimeout": "00:00:00.1000000", "ConnectionIdleTimeout": "00:00:00", "InitPoolTimeout": "00:01:00" } } } ``` -------------------------------- ### Configure EnyimMemcached for Development Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/README.md Use this configuration for local development to easily debug issues. It enables text protocol for human readability and suppresses exceptions to see errors. ```csharp services.AddEnyimMemcached(options => { options.Protocol = MemcachedProtocol.Text; // Easy debugging options.AddServer("localhost", 11211); options.SuppressException = false; // See errors }); ``` -------------------------------- ### Async Get Single Item from Memcached Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/memcached-client.md Asynchronously retrieves a single item from the cache. Use this for non-blocking operations. The result is a Task that resolves to the deserialized value or null if not found. ```csharp var userAsync = await client.GetAsync("user-123"); ``` -------------------------------- ### Get Cached Data (Asynchronous) Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/distributed-cache.md Asynchronously retrieve cached data as bytes using GetAsync. Returns null if the key is not found. Automatically refreshes sliding expiration if set. ```csharp byte[] cachedBytes = await _cache.GetAsync($"user-{userId}"); if (cachedBytes != null) { var json = Encoding.UTF8.GetString(cachedBytes); return JsonSerializer.Deserialize(json); } return null; ``` -------------------------------- ### Check Server Version for Compatibility Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/errors.md Retrieve the server version to identify potential incompatibilities with commands like Touch, SASL authentication, or binary protocol features. ```csharp // Check server version var stats = client.Stats(); var version = stats.GetVersion(ServerStats.All); Console.WriteLine($"Server version: {version}"); // Older servers may not support: // - Touch command // - SASL authentication // - Certain commands in binary protocol ``` -------------------------------- ### Configure SASL PLAIN Authentication Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/configuration.md Set up SASL PLAIN authentication using either a helper method or by manually defining the authentication type and parameters. Ensure correct username and password are provided. ```csharp options.AddPlainTextAuthenticator("", "username", "password"); ``` ```csharp options.Authentication = new Authentication { Type = "Enyim.Caching.Memcached.PlainTextAuthenticator", Parameters = new Dictionary { { "zone", "" }, { "userName", "username" }, { "password", "password" } } }; ``` -------------------------------- ### Serialization and Key Transformation Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/DOCUMENTATION-INDEX.md Documentation on custom serialization (transcoding) and key transformation strategies for the Memcached client. ```APIDOC ## Serialization and Key Transformation ### Description Details the interfaces and implementations for transforming cache keys and serializing/deserializing cache items (transcoding) within the Enyim Memcached client. ### Transcoder Interface (`ITranscoder`) - **DefaultTranscoder**: The standard JSON-based transcoder. - **MessagePackTranscoder**: Uses MessagePack for efficient binary serialization. - **DataContractTranscoder**: Utilizes .NET DataContract serialization. - **BinaryFormatterTranscoder**: Uses .NET BinaryFormatter for serialization. - **Custom transcoder implementation**: Guidance on creating custom transcoders. ### Key Transformer Interface (`IMemcachedKeyTransformer`) - **DefaultKeyTransformer**: The default key transformation behavior. - **Base64KeyTransformer**: Encodes keys using Base64. - **SHA1KeyTransformer**: Transforms keys using SHA1 hashing. - **TigerHashKeyTransformer**: Uses TigerHash for key transformation. - **Custom transformer implementation**: Guidance on creating custom key transformers. ### Related Structures - **CacheItem**: Represents an item stored in the cache, including value and flags. ### Recommendations - **Recommended combinations**: Suggestions for pairing transcoders and key transformers. - **Performance comparison**: Analysis of performance characteristics for different options. ``` -------------------------------- ### Configure Text Protocol Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/configuration.md Set the protocol to Text for human-readable debugging and better compatibility with older servers. Note lower performance. ```json { "enyimMemcached": { "Protocol": "Text" } } ``` -------------------------------- ### Try Get Item from Cache Source: https://github.com/cnblogs/enyimmemcachedcore/blob/main/_autodocs/api-reference/memcached-client.md Attempts to retrieve an item from cache without throwing exceptions. Returns true if the item was found, false otherwise. The retrieved value is provided via an out parameter. ```csharp bool TryGet(string key, out T value) ``` ```csharp if (client.TryGet("user-123", out var user)) { // User found in cache } else { // User not in cache } ```