Guest User

Untitled

a guest
Dec 16th, 2017
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.74 KB | None | 0 0
  1. using Castle.DynamicProxy;
  2. using Newtonsoft.Json;
  3. using System;
  4. using System.Collections.Concurrent;
  5. using System.IO;
  6.  
  7. namespace Utils {
  8. public class JsonSettingProvider<T> where T : class, new() {
  9.  
  10. private static string settingFileDir = AppDomain.CurrentDomain.BaseDirectory;
  11. private static string settingFileName = typeof(T).Name + ".config";
  12. private static string settingFile = Path.Combine(settingFileDir, settingFileName);
  13. private volatile static bool loaded = false;
  14. private volatile static bool innerSet = false;
  15. private static T setting = new T();
  16. private static FileSystemWatcher fsw;
  17. private static object locker = new object();
  18.  
  19. static JsonSettingProvider() {
  20. if (!File.Exists(settingFile)) {
  21. if (!Directory.Exists(settingFileDir)) {
  22. Directory.CreateDirectory(settingFileDir);
  23. }
  24. Save();
  25. }
  26.  
  27. fsw = new FileSystemWatcher(settingFileDir, settingFileName);
  28. fsw.IncludeSubdirectories = false;
  29. fsw.Changed += Fsw_Changed;
  30. fsw.EnableRaisingEvents = true;
  31. }
  32.  
  33.  
  34. public static T Setting {
  35. get {
  36. if (loaded) {
  37. return setting;
  38. }
  39.  
  40. lock (locker) {
  41. var settingInFile = JsonConvert.DeserializeObject<T>(File.ReadAllText(settingFile));
  42. ProxyGenerator generator = new ProxyGenerator();
  43. setting = generator.CreateClassProxyWithTarget<T>(settingInFile, new SettingChangeInterceptor());
  44.  
  45. try {
  46. innerSet = true;
  47. foreach (var property in settingInFile.GetType().GetProperties()) {
  48. var obj = property.GetValue(settingInFile);
  49. property.SetValue(setting, obj);
  50. }
  51. } finally {
  52. innerSet = false;
  53. }
  54.  
  55. loaded = true;
  56. }
  57.  
  58. return setting;
  59. }
  60. }
  61.  
  62. private static void Fsw_Changed(object sender, FileSystemEventArgs e) {
  63. loaded = false;
  64. }
  65.  
  66. private static void Save() {
  67. var data = JsonConvert.SerializeObject(setting, Formatting.Indented);
  68.  
  69. try {
  70. if (fsw != null) fsw.EnableRaisingEvents = false;
  71. File.WriteAllText(settingFile, data);
  72. } finally {
  73. if (fsw != null) fsw.EnableRaisingEvents = true;
  74. }
  75.  
  76. loaded = true;
  77. }
  78.  
  79. class SettingChangeInterceptor : StandardInterceptor {
  80. private ConcurrentDictionary<string, object> OrignalValues = new ConcurrentDictionary<string, object>();
  81.  
  82. protected override void PreProceed(IInvocation invocation) {
  83. if (invocation.Method.Name.StartsWith("set_")) {
  84. var propertyName = invocation.Method.Name.Substring(4);
  85. var orignalValue = invocation.TargetType.GetMethod("get_" + propertyName).Invoke(invocation.Proxy, new object[] { });
  86. OrignalValues.AddOrUpdate(propertyName, orignalValue, (k, v) => orignalValue);
  87. }
  88. }
  89.  
  90. protected override void PostProceed(IInvocation invocation) {
  91. if (!innerSet && invocation.Method.Name.StartsWith("set_")) {
  92. var propertyName = invocation.Method.Name.Substring(4);
  93. var orignalValue = OrignalValues[propertyName];
  94. if (orignalValue != invocation.GetArgumentValue(0)) {
  95. Save();
  96. }
  97. }
  98. }
  99. }
  100. }
  101. }
Add Comment
Please, Sign In to add comment