基於MVC插件模式構建支持數據庫集羣、數據實時同步、數據發佈與訂閱的Web框架系統。以下圖:數據庫
採用插件模式開發的優勢是使得系統框架和業務模式有效地進行分離,系統更新也比較簡單,只需更新業務插件,不須要動整個框架,開發人員無需關心整個框架結構。服務器
但插件模式調試稍微麻煩一點,比不採用插件模式開發的效率上也要差一點,由於它採用反射進行動態加載插件。微信
登陸插件示例:app
namespace LoginPlugin { public class Plugin : NetUML.Portal.Framework.AbstractPlugin { public Plugin() { this.Title = "系統登陸"; this.Description = "登陸插件"; } public override string Name { get { return "LoginPlugin"; } set { } } public override int StartLevel { get { return 2; } set { } } public override void Start(NetUML.Portal.Framework.IBundleContext context) { } public override void Stop(NetUML.Portal.Framework.IBundleContext context) { } public override string SymbolicName { set { } get { return "System.Login"; } } public override List<NetUML.Portal.Framework.MenuItem> MenuItems { get { return null; } } public override NetUML.Portal.Framework.PluginType PluginType { get { return NetUML.Portal.Framework.PluginType.Login; } } public override string Title { get; set; } public override string Description { get; set; } } }
全部插件必須實現 NetUML.Portal.Framework.AbstractPlugin 這個插件抽象類。框架
當加載插件的時候會執行Start方法,中止插件的時候會執行Stop方法。ide
數據庫引擎NetUML.DataEngine類,採用IBatisNet底層訪問數據庫原理,動態建立IDbConnection鏈接池,核心代碼以下this
1 namespace NetUML.DataEngine 2 { 3 public class DbSession : MarshalByRefObject, IDalSession 4 { 5 6 #region Fields 7 private IDataSource _dataSource = null; 8 private bool _isTransactionOpen = false; 9 private bool _consistent = false; 10 private IDbConnection _connection = null; 11 private IDbTransaction _transaction = null; 12 #endregion 13 public DbSession(IDataSource dataSource) 14 { 15 _dataSource = dataSource; 16 } 17 public IDataSource DataSource 18 { 19 get { return _dataSource; } 20 } 21 22 public System.Data.IDbConnection Connection 23 { 24 get { return _connection; } 25 } 26 27 public System.Data.IDbTransaction Transaction 28 { 29 get { return _transaction; } 30 } 31 32 public bool IsTransactionStart 33 { 34 get { return _isTransactionOpen; } 35 } 36 private bool Consistent 37 { 38 set { _consistent = value; } 39 } 40 public void Complete() 41 { 42 this.Consistent = true; 43 } 44 45 public void OpenConnection() 46 { 47 this.OpenConnection(_dataSource.ConnectionString); 48 } 49 public void OpenConnection(string connectionString) 50 { 51 if (_connection == null) 52 { 53 CreateConnection(connectionString); 54 try 55 { 56 _connection.Open(); 57 //if (_logger.IsDebugEnabled) 58 //{ 59 // _logger.Debug(string.Format("Open Connection \"{0}\" to \"{1}\".", _connection.GetHashCode().ToString(), _dataSource.DbProvider.Description)); 60 //} 61 } 62 catch (Exception ex) 63 { 64 //DataMapperException 65 throw new Exception(string.Format("Unable to open connection to \"{0}\".", _dataSource.DbProvider.Description), ex); 66 } 67 } 68 else if (_connection.State != ConnectionState.Open) 69 { 70 try 71 { 72 _connection.Open(); 73 //if (_logger.IsDebugEnabled) 74 //{ 75 // _logger.Debug(string.Format("Open Connection \"{0}\" to \"{1}\".", _connection.GetHashCode().ToString(), _dataSource.DbProvider.Description)); 76 //} 77 } 78 catch (Exception ex) 79 { 80 throw new Exception(string.Format("Unable to open connection to \"{0}\".", _dataSource.DbProvider.Description), ex); 81 } 82 } 83 } 84 public void CreateConnection() 85 { 86 CreateConnection(_dataSource.ConnectionString); 87 } 88 /// <summary> 89 /// Create the connection 90 /// </summary> 91 public void CreateConnection(string connectionString) 92 { 93 _connection = _dataSource.DbProvider.CreateConnection(); 94 _connection.ConnectionString = connectionString; 95 } 96 97 public void CloseConnection() 98 { 99 if ((_connection != null) && (_connection.State != ConnectionState.Closed)) 100 { 101 _connection.Close(); 102 //if (_logger.IsDebugEnabled) 103 //{ 104 // _logger.Debug(string.Format("Close Connection \"{0}\" to \"{1}\".", _connection.GetHashCode().ToString(), _dataSource.DbProvider.Description)); 105 //} 106 _connection.Dispose(); 107 } 108 _connection = null; 109 } 110 111 public void BeginTransaction() 112 { 113 this.BeginTransaction(_dataSource.ConnectionString); 114 } 115 116 public void BeginTransaction(string connectionString) 117 { 118 if (_connection == null || _connection.State != ConnectionState.Open) 119 { 120 this.OpenConnection(connectionString); 121 } 122 _transaction = _connection.BeginTransaction(); 123 //if (_logger.IsDebugEnabled) 124 //{ 125 // _logger.Debug("Begin Transaction."); 126 //} 127 _isTransactionOpen = true; 128 } 129 public void BeginTransaction(bool openConnection) 130 { 131 if (openConnection) 132 { 133 this.BeginTransaction(); 134 } 135 else 136 { 137 if (_connection == null || _connection.State != ConnectionState.Open) 138 { 139 this.OpenConnection(); 140 } 141 _transaction = _connection.BeginTransaction(); 142 //if (_logger.IsDebugEnabled) 143 //{ 144 // _logger.Debug("Begin Transaction."); 145 //} 146 _isTransactionOpen = true; 147 } 148 } 149 public void BeginTransaction(System.Data.IsolationLevel isolationLevel) 150 { 151 this.BeginTransaction(_dataSource.ConnectionString, isolationLevel); 152 } 153 public void BeginTransaction(string connectionString, System.Data.IsolationLevel isolationLevel) 154 { 155 if (_connection == null || _connection.State != ConnectionState.Open) 156 { 157 this.OpenConnection(connectionString); 158 } 159 _transaction = _connection.BeginTransaction(isolationLevel); 160 //if (_logger.IsDebugEnabled) 161 //{ 162 // _logger.Debug("Begin Transaction."); 163 //} 164 _isTransactionOpen = true; 165 } 166 public void BeginTransaction(bool openConnection, System.Data.IsolationLevel isolationLevel) 167 { 168 this.BeginTransaction(_dataSource.ConnectionString, openConnection, isolationLevel); 169 } 170 public void BeginTransaction(string connectionString, bool openConnection, System.Data.IsolationLevel isolationLevel) 171 { 172 if (openConnection) 173 { 174 this.BeginTransaction(connectionString, isolationLevel); 175 } 176 else 177 { 178 if (_connection == null || _connection.State != ConnectionState.Open) 179 { 180 //DataMapperException 181 throw new Exception("SqlMapSession could not invoke StartTransaction(). A Connection must be started. Call OpenConnection() first."); 182 } 183 _transaction = _connection.BeginTransaction(isolationLevel); 184 //if (_logger.IsDebugEnabled) 185 //{ 186 // _logger.Debug("Begin Transaction."); 187 //} 188 _isTransactionOpen = true; 189 } 190 } 191 public void CommitTransaction() 192 { 193 //if (_logger.IsDebugEnabled) 194 //{ 195 // _logger.Debug("Commit Transaction."); 196 //} 197 _transaction.Commit(); 198 _transaction.Dispose(); 199 _transaction = null; 200 _isTransactionOpen = false; 201 202 if (_connection.State != ConnectionState.Closed) 203 { 204 this.CloseConnection(); 205 } 206 } 207 208 public void CommitTransaction(bool closeConnection) 209 { 210 if (closeConnection) 211 { 212 this.CommitTransaction(); 213 } 214 else 215 { 216 //if (_logger.IsDebugEnabled) 217 //{ 218 // _logger.Debug("Commit Transaction."); 219 //} 220 _transaction.Commit(); 221 _transaction.Dispose(); 222 _transaction = null; 223 _isTransactionOpen = false; 224 } 225 } 226 227 public void RollBackTransaction() 228 { 229 //if (_logger.IsDebugEnabled) 230 //{ 231 // _logger.Debug("RollBack Transaction."); 232 //} 233 _transaction.Rollback(); 234 _transaction.Dispose(); 235 _transaction = null; 236 _isTransactionOpen = false; 237 if (_connection.State != ConnectionState.Closed) 238 { 239 this.CloseConnection(); 240 } 241 } 242 243 public void RollBackTransaction(bool closeConnection) 244 { 245 if (closeConnection) 246 { 247 this.RollBackTransaction(); 248 } 249 else 250 { 251 //if (_logger.IsDebugEnabled) 252 //{ 253 // _logger.Debug("RollBack Transaction."); 254 //} 255 _transaction.Rollback(); 256 _transaction.Dispose(); 257 _transaction = null; 258 _isTransactionOpen = false; 259 } 260 } 261 262 public IDbCommand CreateCommand(CommandType commandType) 263 { 264 IDbCommand command = _dataSource.DbProvider.CreateCommand(); 265 command.CommandType = commandType; 266 command.Connection = _connection; 267 if (_transaction != null) 268 { 269 try 270 { 271 command.Transaction = _transaction; 272 } 273 catch 274 { } 275 } 276 if (_connection != null) 277 { 278 try 279 { 280 command.CommandTimeout = _connection.ConnectionTimeout; 281 } 282 catch (NotSupportedException e) 283 { 284 //if (_logger.IsInfoEnabled) 285 //{ 286 // _logger.Info(e.Message); 287 //} 288 } 289 } 290 return command; 291 } 292 293 public System.Data.IDbDataParameter CreateDataParameter() 294 { 295 return _dataSource.DbProvider.CreateDataParameter(); 296 } 297 public System.Data.IDbDataAdapter CreateDataAdapter() 298 { 299 return _dataSource.DbProvider.CreateDataAdapter(); 300 } 301 public System.Data.IDbDataAdapter CreateDataAdapter(System.Data.IDbCommand command) 302 { 303 IDbDataAdapter dataAdapter = null; 304 dataAdapter = _dataSource.DbProvider.CreateDataAdapter(); 305 dataAdapter.SelectCommand = command; 306 return dataAdapter; 307 } 308 public void Dispose() 309 { 310 //if (_logger.IsDebugEnabled) 311 //{ 312 // _logger.Debug("Dispose SqlMapSession"); 313 //} 314 if (_isTransactionOpen == false) 315 { 316 if (_connection.State != ConnectionState.Closed) 317 { 318 this.CloseConnection(); 319 } 320 } 321 else 322 { 323 if (_consistent) 324 { 325 this.CommitTransaction(); 326 _isTransactionOpen = false; 327 } 328 else 329 { 330 if (_connection.State != ConnectionState.Closed) 331 { 332 this.RollBackTransaction(); 333 _isTransactionOpen = false; 334 } 335 } 336 } 337 } 338 } 339 }
程序結構以下圖:spa
NetUML.DataEngine支持多數據庫鏈接,主持數據庫讀寫分離操做,哪些數據表須要讀寫分離能夠進行相應的配置和管理,相似於MVC中的路由概念,我們能夠配置多條路由表,路由表內容包括數插件
據表名,數據對象關鍵詞以及數據庫信息,用戶保存數據的時候,系統根據要保存的數據表以及數據對象去尋找路由,再根據路由中的配置信息進行提交到數據庫。調試
進在開發中。。。。。。。。
若是第三方系統接入當前系統當中來,當前系統中的數據發生變化,須要立馬通知接入進來的系統,把變化的數據提交給第三方系統,第三方系統接入到數據進行相應的處理。
第三方系統只須要提供給當前系統一個URL地址,當前系統把數據POST到URL地址。
進在開發中。。。。。。。。
系統框架支持上傳插件包,不須要到服務器進行更新程序,上傳完插件包以後,系統自動把插件包解壓出來,進行動態編譯加載插件。
系統框架也支持中止和卸載插件。以下圖:
文檔管理插件支持office等文檔在線瀏覽以及文件轉換,把文檔轉換成HTML文件,支持全文解析和全文搜索功能
進在開發中。。。。。。。。
進在開發中。。。。。。。。