Squashed 'FSI.Lib/' content from commit 6aa4846

git-subtree-dir: FSI.Lib
git-subtree-split: 6aa48465a834a7bfdd9cbeae8d2e4f769d0c0ff8
This commit is contained in:
maier_S
2022-03-23 10:15:26 +01:00
commit a0095a0516
62 changed files with 8405 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
using FSI.Lib.EasyEncryption;
using System;
using System.Collections.Generic;
using System.Reflection;
namespace FSI.Lib.WinSettings
{
/// <summary>
/// Provides an abstract base class for specialized settings classes.
/// </summary>
/// <remarks>
/// <para>
/// Specialized classes should inherit from this class and implement specific storage and
/// retrieval logic for each settings by overriding the
/// <see cref="OnSaveSettings(IEnumerable{Setting})"/> and
/// <see cref="OnLoadSettings(IEnumerable{Setting})"/> methods.
/// </para>
/// <para>
/// Ultimately, the specialized classes will then be overridden by each application's
/// settings class. The public properties in that class will become the settings that
/// are saved by classes that derive from this class.
/// </para>
/// </remarks>
public abstract class Settings
{
private IEnumerable<Setting> SettingsList { get; }
/// <summary>
/// Abstract method called when the settings should be saved. Allows
/// the derived class to save those settings in a specialized way.
/// </summary>
/// <param name="settings">The list of settings to be saved.</param>
public abstract void OnSaveSettings(IEnumerable<Setting> settings);
/// <summary>
/// Abstract method called when the settings sould be loaded. Allows
/// the derived class to load those settings in a specialized way.
/// </summary>
/// <param name="settings">The list of settings to be loaded.</param>
public abstract void OnLoadSettings(IEnumerable<Setting> settings);
/// <summary>
/// Gets the <c>Encryption</c> instance associated with this <c>Settings</c>
/// instance.
/// </summary>
[ExcludedSetting]
public Encryption Encryption { get; }
/// <summary>
/// Constructs a new <see cref="Settings"></see> instance.
/// </summary>
/// <remarks>
/// An exception is thrown if password is null but one or more properties have the
/// <see cref="EncryptedSettingAttribute"></see> attribute.
/// </remarks>
/// <param name="password">Encryption password. Can be <c>null</c> if no
/// properties have the <see cref="EncryptedSettingAttribute"></see>
/// attribute.</param>
public Settings(string password = null)
{
if (password == null)
password = GetType().Namespace.ToString();
SettingsList = BuildSettingsList();
Encryption = password != null ?
new Encryption(password, EncryptionAlgorithm.TripleDes) :
null;
}
/// <summary>
/// Saves all settings.
/// </summary>
public void Save()
{
OnSaveSettings(SettingsList);
}
/// <summary>
/// Loads all settings.
/// </summary>
public void Load()
{
OnLoadSettings(SettingsList);
}
private IEnumerable<Setting> BuildSettingsList()
{
// Iterate through all public instance properties
foreach (PropertyInfo prop in GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
// Ignore properties with ExcludedSetting attribute
if (!Attribute.IsDefined(prop, typeof(ExcludedSettingAttribute)))
{
// Test for supported data type (same types as for Encryption class)
if (!Encryption.IsTypeSupported(prop.PropertyType))
throw new Exception(string.Format("Settings property '{0}' is an unsupported data type '{1}'. Change property type or use ExcludedSetting attribute.",
prop.Name, prop.PropertyType.ToString()));
bool encrypted = Attribute.IsDefined(prop, typeof(EncryptedSettingAttribute));
if (encrypted && Encryption == null)
throw new InvalidOperationException("Encryption password cannot be null if any settings have the EncryptedSetting attribute.");
yield return new Setting(this, prop, encrypted);
}
}
}
}
}