Blogengine. NET architecture and source code analysis series part4: global settings of blog-blogsettings

Source: Internet
Author: User
Tags blogengine

In this article, we will {
Tagshow (Event)
} "> The configuration is analyzed and discussed. The configuration part is far-fetched. However, I always think this configuration part is relatively independent and there are many references for blogengine. net design and implementation.

In an enterprise-level application system, it is essential to configure some system global parameters. How do we handle these configurations?

Generally, there are three steps as follows:

1. Some variable parameters are extracted during business module development.

2. When all business modules are developed, these parameters are classified {
Tagshow (Event)
} "> Store it.

3. Develop corresponding management functions to allow users to set these parameters.

I believe that most developers directly operate on the data in the database. some well-developed systems may make separate pages for user management and use. In essence, they all directly deal with the database, there is not much logic involved. It is more direct. However, in blogengine. Net's {
Tagshow (Event)
} "> Architecture {
Tagshow (Event)
} "> This operation becomes invalid in the model. We cannot perform this operation on the blogengine.. NET database to modify the data in the operating system (unless the application is restarted), because blogengine.. NET database only completes data storage, and all business logic is in blogengine. the core layer is maintained by the object state (refer to my second article ). Someone may wonder if you can further develop a dependency on database tables like cache in ASP. NET {
Tagshow (Event)
} "> Mechanism. I think this problem depends on the requirements. This does not seem to be necessary in blogengine. net.

So how does blogengine. Net implement global settings?

In {
Tagshow (Event)
} "> After installing blogengine. net, go to the background management. We will see many configuration options for classification, including the topic ,{
Tagshow (Event)
} "> Language, culture, and time zone. The logic processing of these configurations is completed through a class in blogengine. Core, that is, blogsettings. Blogsettings only completes blogengine. net global configuration processing. Some specific configurations of widgets described later are not completed here. This is mainly for the purpose of independent configuration, so that widgets can be developed independently.

Blogsettings ):

Attachment: blogsetting.jpg

In addition to the corresponding properties of various configuration items in blogsettings, there is also a static changed event to notify the external global configuration that has changed, so that more extensions can be written. Blogsettings is implemented in singleton mode ({
Tagshow (Event)
} "> The global configuration is system-unique for well-designed applications ).

  1. 1/** // <summary>
  2. 2 // public event used to indicate in settings have been changed.
  3. 3 /// </Summary>
  4. 4 public static event eventhandler <eventargs> changed;
  5. 5/** // <summary>
  6. 6 // Private member to hold Singleton instance.
  7. 7 /// </Summary>
  8. 8 Private Static blogsettings blogsettingssingleton;
  9. 9
  10. 10 instance # region instance
  11. 11/*** // <summary>
  12. 12 // gets the singleton instance of the <see CREF = "blogsettings"/> class.
  13. 13 /// </Summary>
  14. 14 // <value> A singleton instance of the <see CREF = "blogsettings"/> class. </value>
  15. 15 /// <remarks> </remarks>
  16. 16 public static blogsettings instance
  17. 17 {
  18. 18 get
  19. 19 {
  20. 20 if (blogsettingssingleton = NULL)
  21. 21 {
  22. 22 blogsettingssingleton = new blogsettings ();
  23. 23}
  24. 24 return blogsettingssingleton;
  25. 25}
  26. 26}
  27. 27 # endregion

Copy code

Here we can understand why direct modification to the data source cannot be reflected in the running system of blogengine. net.

Blogsettings executes a load method during object construction to load configuration information in all data storage. This loading process is applied. net reflection technology, find the configuration item with the same name as the object property in data storage and forcibly convert its value to the property, of course, the data access here is obtained through the blogservice call described in my third article. Similarly, the configuration is modified by saving the data back to the data storage and using reflection.

  1. 1 blogsettings () # region blogsettings ()
  2. 2/** // <summary>
  3. 3 // initializes a new instance of the <see CREF = "blogsettings"/> class.
  4. 4 /// </Summary>
  5. 5 private blogsettings ()
  6. 6 {
  7. 7 load ();
  8. 8}
  9. 9 # endregion
  10. 10
  11. 11 load () # region load ()
  12. 12/*** // <summary>
  13. 13 // initializes the singleton instance of the <see CREF = "blogsettings"/> class.
  14. 14 /// </Summary>
  15. 15 private void load ()
  16. 16 {
  17. 17 type settingstype = This. GetType ();
  18. 18
  19. 19 //------------------------------------------------------------
  20. 20 // Enumerate through individual settings nodes
  21. 21 //------------------------------------------------------------
  22. 22 system. Collections. Specialized. stringdictionary DIC = providers. blogservice. loadsettings ();
  23. 23
  24. 24 foreach (string key in DIC. Keys)
  25. 25 {
  26. 26 //------------------------------------------------------------
  27. 27 // extract the setting's name/value pair
  28. 28 //------------------------------------------------------------
  29. 29 string name = key;
  30. 30 string value = DIC [Key];
  31. 31
  32. 32 //------------------------------------------------------------
  33. 33 // Enumerate through public properties of this instance
  34. 34 //------------------------------------------------------------
  35. 35 foreach (propertyinfo propertyinformation in settingstype. getproperties ())
  36. 36 {
  37. 37 //------------------------------------------------------------
  38. 38 // determine if configured setting matches current setting based on name
  39. 39 //------------------------------------------------------------
  40. 40 if (propertyinformation. Name. Equals (name, stringcomparison. ordinalignorecase ))
  41. 41 {
  42. 42 //------------------------------------------------------------
  43. 43 // attempt to apply configured setting
  44. 44 //------------------------------------------------------------
  45. 45 try
  46. 46 {
  47. 47 propertyinformation. setvalue (this, convert. changetype (value, propertyinformation. propertytype, cultureinfo. currentculture), null );
  48. 48}
  49. 49 catch
  50. 50 {
  51. 51 // todo: log exception to a common logging framework?
  52. 52}
  53. 53 break;
  54. 54}
  55. 55}
  56. 56}
  57. 57 storagelocation = providers. blogservice. getstoragelocation ();
  58. 58}
  59. 59 # endregion
  60. 60
  61. 61 save () # region save ()
  62. 62/*** // <summary>
  63. 63 // saves the settings to disk.
  64. 64 /// </Summary>
  65. 65 public void save ()
  66. 66 {
  67. 67 system. Collections. Specialized. stringdictionary DIC = new system. Collections. Specialized. stringdictionary ();
  68. 68 type settingstype = This. GetType ();
  69. 69
  70. 70 //------------------------------------------------------------
  71. 71 // Enumerate through settings Properties
  72. 72 //------------------------------------------------------------
  73. 73 foreach (propertyinfo propertyinformation in settingstype. getproperties ())
  74. 74 {
  75. 75 try
  76. 76 {
  77. 77 If (propertyinformation. Name! = "Instance ")
  78. 78 {
  79. 79 //------------------------------------------------------------
  80. 80 // extract property value and its String Representation
  81. 81 //------------------------------------------------------------
  82. 82 object propertyvalue = propertyinformation. getvalue (this, null );
  83. 83 string valueasstring = propertyvalue. tostring ();
  84. 84
  85. 85 //------------------------------------------------------------
  86. 86 // format null/default property values as empty strings
  87. 87 //------------------------------------------------------------
  88. 88 If (propertyvalue. Equals (null ))
  89. 89 {
  90. 90 valueasstring = string. empty;
  91. 91}
  92. 92 If (propertyvalue. Equals (int32.minvalue ))
  93. 93 {
  94. 94 valueasstring = string. empty;
  95. 95}
  96. 96 If (propertyvalue. Equals (single. minvalue ))
  97. 97 {
  98. 98 valueasstring = string. empty;
  99. 99}
  100. 100
  101. 101 //------------------------------------------------------------
  102. 102 // write property name/value pair
  103. 103 //------------------------------------------------------------
  104. 104 DIC. Add (propertyinformation. Name, valueasstring );
  105. 105}
  106. 106}
  107. 107 catch {}
  108. 108}
  109. 109
  110. 110 providers. blogservice. savesettings (DIC );
  111. 111 onchanged ();
  112. 112}
  113. 113 # endregion

Copy code

Client usage (note: the client here refers to the user or caller of blogsettings)

  1. 1 // get SMTP Server
  2. 2 string Server = blogsettings. instance. smtpserver;
  3. 3
  4. 4 // set SMTP Server
  5. 5 blogsettings. instance. smtpserver = "hostname ";
  6. 6 blogsettings. instance. Save ();

Copy code

Summary

From the global configuration section of blogengine. net, we can learn the following points:
1. How the singleton mode is applied in real projects.
2. The implementation of the data access part of the configuration item has a good reference value. You can understand the convenience of. Net reflection for development.
3. The use of static events (blogengine. Net has many examples) allows us to make some external extensions, such as developing a tracking system for monitoring configuration modification.

A good design can be achieved only after constant reconstruction.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.