Read-through Caching Provider Implementation
To use Read-through caching, you need to implement the IReadThruProvider interface for .NET. NCache will use this custom implementation to read data from the data source. Please refer to Configuring Read-through in Administrators' Guide for more details.
Warning
If a Read-through caching provider is specified in client.ncconf in the default-readthru-provider tag and also through API, then the provider in API will overwrite the one specified in client.ncconf.
Prerequisites
- To learn about the standard prerequisites required to work with all NCache server-side features including Read-through caching please refer to the given page on Server Side API Prerequisites.
 - This should be a class library project using Microsoft Visual Studio.
 - For API details refer to: IReadThruProvider, LoadFromSource, LoadDataTypeFromSource.
 
Note
In NCache, Read-through caching providers are configured on the cache level, i.e., for clustered caches all nodes will contain provider configurations and their deployed assemblies.
Sample Implementation
The following code sample provides a sample implementation to configure a Read-through caching provider using the IReadThruProvider class for .NET. The LoadFromSource and LoadDataTypeFromSource methods contain logic to load an object or data type respectively from the configured data source if the object is not found in the cache. Also, the GetConnectionString returns the connection string for the configured data source.
public class SampleReadThruProvider : IReadThruProvider
{
    private SqlConnection _connection;
    // Perform tasks like allocating resources or acquiring connections
    public void Init(IDictionary parameters, string cacheId)
    {
        object server = parameters["server"];
        object userId = parameters["username"];
        object password = parameters["password"];
        object database = parameters["database"];
        string connString = GetConnectionString(server.ToString(), database.ToString(), userId.ToString(), password.ToString());
        if (connString != "")
            _connection = new SqlConnection(connString);
            _connection.Open();
    }
    // Responsible for loading an item from the external data source
    public ProviderCacheItem LoadFromSource(string key)
    {
        // LoadFromDataSource loads data from data source
        object value = LoadFromDataSource(key);
        var cacheItem = new ProviderCacheItem(value);
        return cacheItem;
    }
    // Responsible for loading bulk of items from the external data source
    public IDictionary<string, ProviderCacheItem> LoadFromSource(ICollection<string> keys)
    {
        var dictionary = new Dictionary<string, ProviderCacheItem>();
            foreach (string key in keys)
            {
                // LoadFromDataSource loads data from data source
                dictionary.Add(key, new ProviderCacheItem(LoadFromDataSource(key)));
            }
            return dictionary;
    }
    // Adds ProviderDataTypeItem with enumerable data type
    public ProviderDataTypeItem<IEnumerable> LoadDataTypeFromSource(string key, DistributedDataType dataType)
    {
        IEnumerable value = null;
        ProviderDataTypeItem<IEnumerable> dataTypeItem = null;
        switch (dataType)
        {
            case DistributedDataType.List:
                value = new List<object>()
                {
                    LoadFromDataSource(key)
                };
                dataTypeItem = new ProviderDataTypeItem<IEnumerable>(value);
                break;
            case DistributedDataType.Dictionary:
                value = new Dictionary<string, object>()
                {
                    { key ,  LoadFromDataSource(key) }
                };
                dataTypeItem = new ProviderDataTypeItem<IEnumerable>(value);
                break;
            case DistributedDataType.Counter:
                dataTypeItem = new ProviderDataTypeItem<IEnumerable>(1000);
                break;
        }
        return dataTypeItem;
    }
    // Perform tasks associated with freeing, releasing, or resetting resources.
    public void Dispose()
    {
        if (_connection != null)
        {
            _connection.Close();
        }
    }
    private object LoadFromDataSource(string key)
    {
        object retrievedObject = null;
        // Load item from your data source and populate retrieved Object
        return retrievedObject;
    }
    private string GetConnectionString(string server, string database, string userName, string password)
    {
        string connectionString = null;
            if (!string.IsNullOrEmpty(server))
            {
                connectionString = "Server=" + server + ";";
            }
            else
            {
                // Server name is empty
            }
            if (!string.IsNullOrEmpty(database))
            {
                connectionString = connectionString + "Database=" + database + ";";
            }
            else
            {
                // Database is empty;
            }
            if (!string.IsNullOrEmpty(userName))
            {
                connectionString = connectionString + "User ID=" + userName + ";";
            }
            else
            {
                connectionString = connectionString + "User ID=" + "" + ";";
            }
            if (!string.IsNullOrEmpty(password))
            {
                connectionString = connectionString + "Password=" + password + ";";
            }
            else
            {
                connectionString = connectionString + "Password=" + "" + ";";
            }
        }
        return connectionString;
    }
    // Deploy this class on cache
Important
Make sure to deploy the Read-through provider after implementing the interfaces using the NCache Management Center as guided in Deploy Provider in the Administrators' Guide.
Note
To ensure the operation is fail-safe, it is recommended to handle any potential exceptions within your application, as explained in Handling Failures.
Additional Resources
NCache provides a sample application for Read-through on GitHub.
See Also
.NET: Alachisoft.NCache.Runtime namespace.