Configuring Read-Through Provider
To use Read-through caching, you need to implement the IReadThruProvider
interface provided by NCache. NCache framework will use this custom implementation to read data from the back-end data source. Please refer to Configuring Read-through in Administrators' Guide for more details.
Note that if a read-through provider is specified in client.ncconf in the default-readthru-provider
tag, and has also been specified through API, the provider in API will overwrite the one specified in client.ncconf.
IReadThruProvider Interface
Method | Description |
---|---|
Init |
This method will be called by NCache on cache startup. User can use this method for performing tasks like allocating resources, acquiring connections of data source etc. This method takes as input the HashMap instance of arguments passed to the provider through the NCache Manager (configuration settings). It allows you to pass a list of parameters to the provider. These parameters can be utilized in many ways. For example, the connection string of a data source can be specified as a parameter. Thus, it provides a flexible way to change the data source settings while configuring it without code changes. The other argument CacheId specifies the cache name for which read-through is configured. |
LoadFromSource |
This method will be called by NCache if the required item is not found in cache store and NCache has to load it through configured data source. This method should contain logic to load an object from the configured data source. First argument "key" refers to the key of the required item. The second argument is an out parameter of type ProviderCacheItem which needs to be instantiated along with the required properties. Here you can associate various properties to loaded item before returning it back to NCache framework. Make sure that ProviderCacheItemValue assigned in this method is "Serializable" because NCache will later save that item to cache store to fulfill future requests. While implementing this method, you should take care of code thread safety as multiple Get requests can access this method for read-through. Also do care to avoid scenarios that cause recursive infinite loops e.g. in this method a Get request with read-through on the same cache handle will cause infinite recursion. In case of get, loadFromSource(string key, out ProviderCacheItemcacheItem) will be called from provider while for getBulk, loadFromSource(string[] keys) will be called to load items from data source. |
Dispose |
This method will be called by the NCache framework when the cache stops. You can use this method for performing tasks like releasing resources, disposing connections etc. Here you can free the resources related to the data source for effective resource utilization. |
Note
In NCache, read-through providers are configured on cache level, i.e. for clustered caches all nodes will contain provider configurations and their deployed assemblies.
Sample Implementation of IReadThruProvider
To implement IReadThruProvider, include the following namespace in your application:
Alachisoft.NCache.Runtime.DatasourceProviders
.
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);
try
{
_connection.Open();
}
catch (Exception ex)
{
//handle exception
}
}
//Responsible for loading an item from the external data source.
public void LoadFromSource(string key, out ProviderCacheItem cacheItem)
{
//where LoadFromDataSource is the dummy method to load data from data source.
object value = LoadFromDataSource(key);
cacheItem = new ProviderCacheItem(value);
cacheItem.ResyncItemOnExpiration = true;
}
//Perform tasks associated with freeing, releasing, or resetting resources.
public void Dispose()
{
if (_connection != null)
_connection.Close();
}
//Responsible for loading bulk of items from the external data source.
public Dictionary<string, ProviderCacheItem> LoadFromSource(string[] keys)
{
Dictionary<string, ProviderCacheItem> dictionary = new Dictionary<string, ProviderCacheItem>();
try
{
string key = null;
for (int index = 0; index < keys.Length; index++)
{
key = keys[index];
//where LoadFromDataSource is the dummy method to load data from data source.
dictionary.Add(key, new ProviderCacheItem(LoadFromDataSource(key)));
}
return dictionary;
}
catch (Exception exp)
{
//handle exception
}
return dictionary;
}
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;
try
{
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=" + "" + ";";
}
catch (Exception exp)
{
// handle exception
}
return connectionString;
}
}
See Also
Using Read-Through with Cache Operations