转载构建高性能插件式Web框架

基于MVC插件模式构建支持数据库集群、数据实时同步、数据发布与订阅的Web框架系统。如下图:

  1、基于插件式开发

     采用插件模式开发的优点是使得系统框架和业务模式有效地进行分离,系统更新也比较简单,只需更新业务插件,不需要动整个框架,开发人员无需关心整个框架结构。

但插件模式调试稍微麻烦一点,比不采用插件模式开发的效率上也要差一点,因为它采用反射进行动态加载插件。

登录插件示例:

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方法。

  2、数据库引擎

     数据库引擎NetUML.DataEngine类,采用IBatisNet底层访问数据库原理,动态创建IDbConnection连接池,核心代码如下

  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 }

程序结构如下图:

  3、数据库集群服务

     NetUML.DataEngine支持多数据库连接,主持数据库读写分离操作,哪些数据表需要读写分离可以进行相应的配置和管理,类似于MVC中的路由概念,咱们可以配置多条路由表,路由表内容包括数

据表名,数据对象关键词以及数据库信息,用户保存数据的时候,系统根据要保存的数据表以及数据对象去寻找路由,再根据路由中的配置信息进行提交到数据库。

进在开发中。。。。。。。。

  4、数据同步、发布和订阅服务

     如果第三方系统接入当前系统当中来,当前系统中的数据发生变化,需要立马通知接入进来的系统,把变化的数据提交给第三方系统,第三方系统接入到数据进行相应的处理。

     第三方系统只需要提供给当前系统一个URL地址,当前系统把数据POST到URL地址。

进在开发中。。。。。。。。

  5、插件管理

系统框架支持上传插件包,不需要到服务器进行更新程序,上传完插件包之后,系统自动把插件包解压出来,进行动态编译加载插件。

系统框架也支持停止和卸载插件。如下图:

  6、海量文档资料+全文搜索插件

    文档管理插件支持office等文档在线浏览以及文件转换,把文档转换成HTML文件,支持全文解析和全文搜索功能

进在开发中。。。。。。。。

  7、微信公共帐号订制插件

进在开发中。。。。。。。。

  8、待续.....

  

 
分类: .Net

插件式Web框架的更多相关文章

  1. 构建高性能插件式Web框架

    基于MVC插件模式构建支持数据库集群.数据实时同步.数据发布与订阅的Web框架系统.如下图: 1.基于插件式开发 采用插件模式开发的优点是使得系统框架和业务模式有效地进行分离,系统更新也比较简单,只需 ...

  2. Asp.net MVC 插件式应用框架

    Asp.net MVC 插件式应用框架 2013年05月13日 10:16供稿中心: 互联网运营部 摘要:这几年来做了很多个网站系统,一直坚持使用asp.net mvc建站,每次都从头开始做Layou ...

  3. (1)从底层设计,探讨插件式GIS框架的实现

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 研一时,听当时的师兄推荐,买了蒋波涛的一本关于GIS插件框架的书.当时 ...

  4. 蜗牛历险记(二) Web框架(上)

    接上篇所说,本篇主要内容是讲述如何使用Autofac来管理整个平台的生命周期(初级). 一.简述 插件式Web开发的同学应该还会记得PreApplicationStartMethod这个Assembl ...

  5. 实战基于Spring Boot 2的WebFlux和mLab搭建反应式Web

    Spring Framework 5带来了新的Reactive Stack非阻塞式Web框架:Spring WebFlux.作为与Spring MVC并行使用的Web框架,Spring WebFlux ...

  6. python三大web框架Django,Flask,Flask,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架

    Python几种主流框架 从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python We ...

  7. JAVA web 框架集合

    “框架”犹如滔滔江水连绵不绝, 知道有它就好,先掌握自己工作和主流的框架: 在研究好用和新框架. 主流框架教程分享在Java帮帮-免费资源网 其他教程需要时间制作,会陆续分享!!! 152款框架,你还 ...

  8. Django,Flask,Tornado三大框架对比,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架

    Django 与 Tornado 各自的优缺点Django优点: 大和全(重量级框架)自带orm,template,view 需要的功能也可以去找第三方的app注重高效开发全自动化的管理后台(只需要使 ...

  9. python web框架——初识tornado

    一 Tornado概述 Tornado是FriendFeed使用的可扩展的非阻塞式web框架及其相关工具的开源版本.这个Web框架看起来有些像web.py或者Google的 webapp,不过为了能有 ...

随机推荐

  1. PHPthinking官方论坛

    PHPthinking官方论坛正式上线一个月!眼下.我们已经有数百个固定用户的.论坛发展迅速,所有份额一些技术贴,我们希望,其他许多用户增加来,创建学习.交流更方便.丰富的内容PHP座谈会! PHPt ...

  2. 由<a href = "#" > 引发的思考

    原文:由<a href = "#" > 引发的思考 前阵子在一个移动项目中,通过 <a href = "#" >  的方式 绑定clic ...

  3. 配置Tomcat出现Unsupported major.minor version 51.0

    在配置tomcat时,配置好jdk1.6,下载的tomcat8.0,结果执行start-up.bat,总是一闪而过,网上查了大量的资料,都说是可能是jdk没配置好,但实际上jdk的环境变量设置正常,后 ...

  4. 大约linux的几个问题,你能回答几个?--回复14-20称号

    14.select和poll差异?Poll和epoll的差别? (1)select和poll的差别:(參考:http://blog.csdn.net/mituan2008/article/detail ...

  5. 【j2ee spring】30、巴巴荆楚网-综合hibernate4+spring4(5)分页

    巴巴荆楚网-综合hibernate4+spring4(5)分页 1.图文项目 2.首先我们引入对应的jar包 3.我们配置一下数据库中对应的实体对象 ProductType.java /** * 功能 ...

  6. 跳转表C语言,不比redis版本号

    本来跳表的原理很easy的(相对于红 - 黑树),但国庆间歇性地搞5天才捞起来-- 我学会了跳之前写表的链式结构完全基于,我看着写的过程中redis实现,它的每个键列都是用数组来表示的.细致想了想发现 ...

  7. Android+NDK+CDT+eclipse+OPenGL ES编制和native调试

    周围环境: NDK版本号r8,eclipse和Android运用adt-bundle-windows-x86打包版本是更方便, 一.NDK汇集 1.源代码 NDK的examples文件夹中有Hello ...

  8. RH253读书笔记(1)-Lab 1 System Monitoring

    Lab 1 System Monitoring Goal: To build skills to better assess system resources, performance and sec ...

  9. 读改善c#代码157个建议:建议7~9

    目录: 建议7:将0值作为枚举的默认值 建议8:避免给枚举类型的元素提供显示的值 建议9:习惯运算符重载 一.建议7:将0值作为枚举的默认值 允许使用的枚举类型有:byte.sbyte.short.u ...

  10. [SignalR]一个简单的聊天室

    原文:[SignalR]一个简单的聊天室 1.说明 开发环境:Microsoft Visual Studio 2010 以及需要安装NuGet. 2.添加SignalR所需要的类库以及脚本文件: 3. ...