Ik schrijf dit topic niet zozeer omdat ik een enorm probleem heb, maar meer omdat ik tegen een redelijk intellectueel uitdagend inheritance/design pattern probleem aan ben gelopen bij een eigen projectje. (Ten minste, ik hoop dat het intellectueel uitdagend is, anders heb ik over iets heen gekeken)
Probleem voorstelling:
Ik heb een programma, dat programma heeft settings, die moeten worden opgeslagen en opgehaald worden bij het respectievelijk sluiten en opstarten van het programma. Die settings wil ik graag gescheiden houden, maar wel in 1 keer kunnen saven. Voorbeeldje:
Ik wil drie settings classes hebben: (fictief)
1. UISettings
2. LibrarySettings
3. GlobalizationSettings
En in 1 statement kunnen opslaan bij het sluiten van mn programma:
Settings.SaveAll() // bijvoorbeeld..
Alle settings classes zijn natuurlijk singleton. (Static kan niet, dan kan je ze namelijk niet serializen?)
Het lijkt me makkelijk om een base class te hebben die al het benodigde laden en opslaan van *alle* settings classes kan doen.
Mijn oplossing: (Let vooral op GetInstance<>(), de rest vloeit daaruit voort.)
Dit werkt goed. (Alleen is het voor buitenstaanders waarschijnlijk bijna onmogelijk om te begrijpen hoe ze een een instance kunnen krijgen ivm de Generic GetInstance<T>().. )
Het probleem met deze oplossing is alleen dat child Settings classes een public constructor moet hebben ivm GetInstance<>().. (Een Generic type mag van de C# compiler niet genewed worden als de constructor niet public is. )
Dat doet het hele gedoe weer teniet. Maar aangezien dit een compleet doe het zelf projectje is, ben ik de enige die er rekening mee hoeft te houden, dus de kans op fouten is niet zo groot. (Alleen de kans dat ik op den duur de werking van de GetInstance<>() vergeet is natuurlijk wel aanwezig
)
Wat wel een voordeel is, is dat een child class er nu zo uitziet:
Er is 1 oplossing die waarschijnlijk het best zou werken:
Iedere child-class een onafhangelijke GetInstance() en een destructor. En dan uiteindelijk alsnog de base class het opslaan en laden laten regelen.
Iemand nog leuke, interessante of ronduit vreemde suggesties?
Probleem voorstelling:
Ik heb een programma, dat programma heeft settings, die moeten worden opgeslagen en opgehaald worden bij het respectievelijk sluiten en opstarten van het programma. Die settings wil ik graag gescheiden houden, maar wel in 1 keer kunnen saven. Voorbeeldje:
Ik wil drie settings classes hebben: (fictief)
1. UISettings
2. LibrarySettings
3. GlobalizationSettings
En in 1 statement kunnen opslaan bij het sluiten van mn programma:
Settings.SaveAll() // bijvoorbeeld..
Alle settings classes zijn natuurlijk singleton. (Static kan niet, dan kan je ze namelijk niet serializen?)
Het lijkt me makkelijk om een base class te hebben die al het benodigde laden en opslaan van *alle* settings classes kan doen.
Mijn oplossing: (Let vooral op GetInstance<>(), de rest vloeit daaruit voort.)
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
| public abstract class Settings { protected string fileName; // De filenaam van de file waarin de setting wordt opgeslagen. protected static List<Settings> allSettings = new List<Settings>(); protected static bool ContainsSetting(Type t) {// Kijkt in allSettings of er een Setting van type t tussen zit. } protected static T GetSetting<T>() where T: Settings {// returned de setting in allSettings van type T, anders null. } protected void Save() {// Saved 'this' (Let op: geen static! } protected static T Load<T>(string filename) where T: Settings { // Haalt object op uit IsolatedStorage. // Returned object as T. // (dus null als het bestand waar filename naar verwijst niet van type T is. } public static T GetInstance<T>() where T : Settings, new() { // Check if an instance of T already exists: if (Settings.ContainsSetting(typeof(T))) return GetSetting<T>(); // load instance: T instance = Load<T>(new T().fileName); // if loading didn't succeed, return a new(default) instance: if (instance == null) instance = new T(); // if loading did succeed, do not forget to add to allSettings: allSettings.Add(instance); return instance; } public static void SaveSettings() { foreach (Settings setting in allSettings) setting.Save(); } } |
Dit werkt goed. (Alleen is het voor buitenstaanders waarschijnlijk bijna onmogelijk om te begrijpen hoe ze een een instance kunnen krijgen ivm de Generic GetInstance<T>().. )
Het probleem met deze oplossing is alleen dat child Settings classes een public constructor moet hebben ivm GetInstance<>().. (Een Generic type mag van de C# compiler niet genewed worden als de constructor niet public is. )
Dat doet het hele gedoe weer teniet. Maar aangezien dit een compleet doe het zelf projectje is, ben ik de enige die er rekening mee hoeft te houden, dus de kans op fouten is niet zo groot. (Alleen de kans dat ik op den duur de werking van de GetInstance<>() vergeet is natuurlijk wel aanwezig
Wat wel een voordeel is, is dat een child class er nu zo uitziet:
C#:
1
2
3
4
5
6
7
8
9
10
11
| [Serializable] public class KeyWordSettings : Settings { const string settingFileName = "KeywordSetting.conf"; public KeyWordSettings() : base(settingFileName) { } // En hier natuurlijk nog de inhoud qua setting fields en properties. } |
Er is 1 oplossing die waarschijnlijk het best zou werken:
Iedere child-class een onafhangelijke GetInstance() en een destructor. En dan uiteindelijk alsnog de base class het opslaan en laden laten regelen.
Iemand nog leuke, interessante of ronduit vreemde suggesties?