bovender framework
C# framework that implements MVVM and more
UserSettingsBase.cs
1 /* Settings.cs
2  * part of Bovender framework
3  *
4  * Copyright 2014-2018 Daniel Kraus
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 using System;
19 using System.Collections;
20 using System.Collections.Generic;
21 using System.Linq;
22 using System.Text;
23 using System.IO;
24 using YamlDotNet.Core;
25 using YamlDotNet.Serialization;
26 
27 namespace Bovender.UserSettings
28 {
39  public class UserSettingsBase
40  {
41  #region Singleton
42 
50  public static UserSettingsBase Default
51  {
52  get
53  {
54  return _lazy.Value;
55  }
56  set
57  {
58  _lazy = new Lazy<UserSettingsBase>(() => value);
59  }
60  }
61 
62  private static Lazy<UserSettingsBase> _lazy = new Lazy<UserSettingsBase>(() => new UserSettingsBase());
63 
64  #endregion
65 
66  #region Factory
67 
80  protected static T FromFileOrDefault<T>(string yamlFile, DeserializerBuilder deserializerBuilder)
81  where T: UserSettingsBase, new()
82  {
83  if (deserializerBuilder == null)
84  {
85  throw new ArgumentNullException("deserializerBuilder",
86  "Must provide a DeserializerBuilder object to load settings.");
87  }
88  T optionsStore = null;
89  if (File.Exists(yamlFile))
90  {
91  try
92  {
93  using (FileStream fs = File.Open(yamlFile, FileMode.Open, FileAccess.Read, FileShare.Read))
94  {
95  StreamReader sr = new StreamReader(fs);
96  Deserializer des = deserializerBuilder.Build();
97  optionsStore = des.Deserialize<T>(sr);
98  if (optionsStore != null)
99  {
100  optionsStore.WasFromFile = true;
101  }
102  }
103  Logger.Info("Loaded user settings from file '{0}'", yamlFile);
104  }
105  catch (IOException e)
106  {
107  optionsStore = CreateDefaultOnException<T>(e);
108  }
109  catch (YamlException e)
110  {
111  optionsStore = CreateDefaultOnException<T>(e);
112  }
113  }
114  if (optionsStore == null)
115  {
116  Logger.Info("Creating user settings object from scratch");
117  optionsStore = new T();
118  }
119  return optionsStore;
120  }
121 
133  protected static T FromFileOrDefault<T>(string yamlFile)
134  where T : UserSettingsBase, new()
135  {
136  return FromFileOrDefault<T>(yamlFile, new DeserializerBuilder().IgnoreUnmatchedProperties());
137  }
138 
139  #endregion
140 
141  #region User settings
142 
143  public string User
144  {
145  get
146  {
147  if (_user == null)
148  {
149  _user = "";
150  }
151  return _user;
152  }
153  set
154  {
155  _user = value;
156  }
157  }
158 
159  public string Email
160  {
161  get
162  {
163  if (_email == null)
164  {
165  _email = "";
166  }
167  return _email;
168  }
169  set
170  {
171  _email = value;
172  }
173  }
174 
175  public bool CcUserOnExceptionReport
176  {
177  get
178  {
179  if (_ccUserOnExceptionReport == null)
180  {
181  _ccUserOnExceptionReport = true;
182  }
183  return (bool)_ccUserOnExceptionReport;
184  }
185  set
186  {
187  _ccUserOnExceptionReport = value;
188  }
189  }
190 
191  public string DownloadFolder
192  {
193  get
194  {
195  if (_downloadFolder == null)
196  {
197  _downloadFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
198  }
199  return _downloadFolder;
200  }
201  set
202  {
203  _downloadFolder = value;
204  }
205  }
206 
207  #endregion
208 
209  #region Public static methods
210 
221  public static void LoadDefaults()
222  {
223  _lazy = new Lazy<UserSettingsBase>(() => new UserSettingsBase());
224  }
225 
226  #endregion
227 
228  #region Properties that are not being saved to the YAML file
229 
234  [YamlIgnore]
235  public bool WasFromFile { get; protected set; }
236 
240  [YamlIgnore]
241  public Exception Exception { get; protected set; }
242 
243  #endregion
244 
245  #region Constructor
246 
247  public UserSettingsBase() { }
248 
249  #endregion
250 
251  #region Save to file
252 
256  public void Save()
257  {
258  try
259  {
260  string fn = GetSettingsFilePath();
261  Directory.CreateDirectory(System.IO.Path.GetDirectoryName(fn));
262  using (FileStream fs = File.Open(fn, FileMode.Create, FileAccess.Write))
263  {
264  StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
265  WriteYamlHeader(sw);
266  Serializer ser = ConstructSerializerBuilder().Build();
267  ser.Serialize(sw, this);
268  sw.Flush();
269  }
270  Exception = null;
271  Logger.Info("Saved user settings to file '{0}'", fn);
272  }
273  catch (IOException e)
274  {
275  Logger.Warn("Could not save user settings", e);
276  Exception = e;
277  }
278  }
279 
292  protected virtual SerializerBuilder ConstructSerializerBuilder()
293  {
294  return new SerializerBuilder();
295  }
296 
303  public virtual string GetSettingsFilePath()
304  {
305  return System.IO.Path.Combine(
306  Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
307  Properties.Settings.Default.UserSettingsPath,
308  Properties.Settings.Default.UserSettingsFile);
309  }
310 
315  protected virtual void WriteYamlHeader(StreamWriter streamWriter)
316  {
317  streamWriter.WriteLine("# !!! DO NOT EDIT THIS FILE WHILE THE APPLICATION IS RUNNING !!!");
318  }
319 
320  #endregion
321 
322  #region Private fields
323 
324  private string _user;
325  private string _email;
326 
331  private bool? _ccUserOnExceptionReport;
332 
333  private string _downloadFolder;
334 
335  #endregion
336 
337  #region Private static method
338 
346  private static T CreateDefaultOnException<T>(Exception e)
347  where T: UserSettingsBase, new()
348  {
349  Logger.Warn(e, "Exception during loading of user settings, using default");
350  T options = new T();
351  options.Exception = e;
352  return options;
353  }
354 
355  #endregion
356 
357  #region Class logger
358 
359  private static NLog.Logger Logger { get { return _logger.Value; } }
360 
361  private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
362 
363  #endregion
364  }
365 }
static void LoadDefaults()
Creates a new settings object without loading the saved settings from file and without saving the cur...
void Save()
Saves the user settings to a file.
Base class for persistent settings; a replacement for the UserSettings.UserSettingsBase system which ...
virtual string GetSettingsFilePath()
Gets the complete path and file name for the user settings file.
virtual SerializerBuilder ConstructSerializerBuilder()
Builds a YamlDotNet serializer builder.
virtual void WriteYamlHeader(StreamWriter streamWriter)
Writes a header to the YAML file before all other data.