While browsing the Dynamics CRM 2011 Development forum I came across a post asking where people store their settings for ISV extensions. The way I’ve done this is by creating a custom entity called “Settings” with 3 fields, Key, Value and Encrypted (yes/no).
Then we have a helper class that gets these values. Here’s an example
Couple of things to note, the EncryptDecrypt method is blanked out, you’ll need to implement your own encryption and decryption routine.
The Get method only has a few known type castings, add more as required.
public class Setting
{
private IOrganizationService _sdk = null;
public Setting(IOrganizationService context)
{
_sdk = context;
}
#region encryption
internal static string EncryptDecrypt(string textToEncrypt)
{
return textToEncrypt; // up to you to implement encryption
}
#endregion
// some common type castings, you can add more if required
public T Get<T>(string key)
{
string value = this[key];
if (!string.IsNullOrEmpty(value))
{
if (typeof(T) == typeof(string))
{
return (T)Convert.ChangeType(value, typeof(string));
}
if (typeof(T) == typeof(int))
{
return (T)Convert.ChangeType(int.Parse(value), typeof(int));
}
if (typeof(T) == typeof(decimal))
{
return (T)Convert.ChangeType(decimal.Parse(value), typeof(decimal));
}
if (typeof(T) == typeof(DateTime))
{
return (T)Convert.ChangeType(DateTime.Parse(value), typeof(DateTime));
}
}
return default(T);
}
#region settings storage
private Dictionary<string, string> _values = new Dictionary<string, string>();
private Dictionary<string, Guid> _cached = new Dictionary<string, Guid>();
internal string this[string key]
{
get
{
if (_values == null || _values.Count == 0) { Refresh(); }
if (_values.Keys.Contains(key))
{
return _values[key];
}
return "";
}
set
{
}
}
#endregion
#region helper methods
public void Refresh()
{
_cached.Clear();
// get all the settings and parse it into a collection first
QueryExpression qe = new QueryExpression("mag_setting") { ColumnSet = new ColumnSet(true) };
var results = _sdk.RetrieveMultiple(qe);
if (results != null && results.Entities != null && results.Entities.Count > 0)
{
results.Entities.ToList().ForEach(setting =>
{
var current = setting as Entity;
Guid id = current.Get<Guid>("mag_settingid");
bool encrypted = current.Get<bool>("mag_encrypted");
string key = current.Get<string>("mag_key");
string value = current.Get<string>("mag_value");
if (encrypted) { value = EncryptDecrypt(value); } // decrypt if the setting is encrypted
// make sure we don't double up on the settings, otherwise .net will throw an error
if (!_cached.Keys.Contains(key)) { _cached.Add(key, id); }
if (!_values.Keys.Contains(key)) { _values.Add(key, value); }
});
}
}
#endregion
}