基于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 ; }
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连接池,核心代码如下

 namespace NetUML.DataEngine
{
public class DbSession : MarshalByRefObject, IDalSession
{ #region Fields
private IDataSource _dataSource = null;
private bool _isTransactionOpen = false;
private bool _consistent = false;
private IDbConnection _connection = null;
private IDbTransaction _transaction = null;
#endregion
public DbSession(IDataSource dataSource)
{
_dataSource = dataSource;
}
public IDataSource DataSource
{
get { return _dataSource; }
} public System.Data.IDbConnection Connection
{
get { return _connection; }
} public System.Data.IDbTransaction Transaction
{
get { return _transaction; }
} public bool IsTransactionStart
{
get { return _isTransactionOpen; }
}
private bool Consistent
{
set { _consistent = value; }
}
public void Complete()
{
this.Consistent = true;
} public void OpenConnection()
{
this.OpenConnection(_dataSource.ConnectionString);
}
public void OpenConnection(string connectionString)
{
if (_connection == null)
{
CreateConnection(connectionString);
try
{
_connection.Open();
//if (_logger.IsDebugEnabled)
//{
// _logger.Debug(string.Format("Open Connection \"{0}\" to \"{1}\".", _connection.GetHashCode().ToString(), _dataSource.DbProvider.Description));
//}
}
catch (Exception ex)
{
//DataMapperException
throw new Exception(string.Format("Unable to open connection to \"{0}\".", _dataSource.DbProvider.Description), ex);
}
}
else if (_connection.State != ConnectionState.Open)
{
try
{
_connection.Open();
//if (_logger.IsDebugEnabled)
//{
// _logger.Debug(string.Format("Open Connection \"{0}\" to \"{1}\".", _connection.GetHashCode().ToString(), _dataSource.DbProvider.Description));
//}
}
catch (Exception ex)
{
throw new Exception(string.Format("Unable to open connection to \"{0}\".", _dataSource.DbProvider.Description), ex);
}
}
}
public void CreateConnection()
{
CreateConnection(_dataSource.ConnectionString);
}
/// <summary>
/// Create the connection
/// </summary>
public void CreateConnection(string connectionString)
{
_connection = _dataSource.DbProvider.CreateConnection();
_connection.ConnectionString = connectionString;
} public void CloseConnection()
{
if ((_connection != null) && (_connection.State != ConnectionState.Closed))
{
_connection.Close();
//if (_logger.IsDebugEnabled)
//{
// _logger.Debug(string.Format("Close Connection \"{0}\" to \"{1}\".", _connection.GetHashCode().ToString(), _dataSource.DbProvider.Description));
//}
_connection.Dispose();
}
_connection = null;
} public void BeginTransaction()
{
this.BeginTransaction(_dataSource.ConnectionString);
} public void BeginTransaction(string connectionString)
{
if (_connection == null || _connection.State != ConnectionState.Open)
{
this.OpenConnection(connectionString);
}
_transaction = _connection.BeginTransaction();
//if (_logger.IsDebugEnabled)
//{
// _logger.Debug("Begin Transaction.");
//}
_isTransactionOpen = true;
}
public void BeginTransaction(bool openConnection)
{
if (openConnection)
{
this.BeginTransaction();
}
else
{
if (_connection == null || _connection.State != ConnectionState.Open)
{
this.OpenConnection();
}
_transaction = _connection.BeginTransaction();
//if (_logger.IsDebugEnabled)
//{
// _logger.Debug("Begin Transaction.");
//}
_isTransactionOpen = true;
}
}
public void BeginTransaction(System.Data.IsolationLevel isolationLevel)
{
this.BeginTransaction(_dataSource.ConnectionString, isolationLevel);
}
public void BeginTransaction(string connectionString, System.Data.IsolationLevel isolationLevel)
{
if (_connection == null || _connection.State != ConnectionState.Open)
{
this.OpenConnection(connectionString);
}
_transaction = _connection.BeginTransaction(isolationLevel);
//if (_logger.IsDebugEnabled)
//{
// _logger.Debug("Begin Transaction.");
//}
_isTransactionOpen = true;
}
public void BeginTransaction(bool openConnection, System.Data.IsolationLevel isolationLevel)
{
this.BeginTransaction(_dataSource.ConnectionString, openConnection, isolationLevel);
}
public void BeginTransaction(string connectionString, bool openConnection, System.Data.IsolationLevel isolationLevel)
{
if (openConnection)
{
this.BeginTransaction(connectionString, isolationLevel);
}
else
{
if (_connection == null || _connection.State != ConnectionState.Open)
{
//DataMapperException
throw new Exception("SqlMapSession could not invoke StartTransaction(). A Connection must be started. Call OpenConnection() first.");
}
_transaction = _connection.BeginTransaction(isolationLevel);
//if (_logger.IsDebugEnabled)
//{
// _logger.Debug("Begin Transaction.");
//}
_isTransactionOpen = true;
}
}
public void CommitTransaction()
{
//if (_logger.IsDebugEnabled)
//{
// _logger.Debug("Commit Transaction.");
//}
_transaction.Commit();
_transaction.Dispose();
_transaction = null;
_isTransactionOpen = false; if (_connection.State != ConnectionState.Closed)
{
this.CloseConnection();
}
} public void CommitTransaction(bool closeConnection)
{
if (closeConnection)
{
this.CommitTransaction();
}
else
{
//if (_logger.IsDebugEnabled)
//{
// _logger.Debug("Commit Transaction.");
//}
_transaction.Commit();
_transaction.Dispose();
_transaction = null;
_isTransactionOpen = false;
}
} public void RollBackTransaction()
{
//if (_logger.IsDebugEnabled)
//{
// _logger.Debug("RollBack Transaction.");
//}
_transaction.Rollback();
_transaction.Dispose();
_transaction = null;
_isTransactionOpen = false;
if (_connection.State != ConnectionState.Closed)
{
this.CloseConnection();
}
} public void RollBackTransaction(bool closeConnection)
{
if (closeConnection)
{
this.RollBackTransaction();
}
else
{
//if (_logger.IsDebugEnabled)
//{
// _logger.Debug("RollBack Transaction.");
//}
_transaction.Rollback();
_transaction.Dispose();
_transaction = null;
_isTransactionOpen = false;
}
} public IDbCommand CreateCommand(CommandType commandType)
{
IDbCommand command = _dataSource.DbProvider.CreateCommand();
command.CommandType = commandType;
command.Connection = _connection;
if (_transaction != null)
{
try
{
command.Transaction = _transaction;
}
catch
{ }
}
if (_connection != null)
{
try
{
command.CommandTimeout = _connection.ConnectionTimeout;
}
catch (NotSupportedException e)
{
//if (_logger.IsInfoEnabled)
//{
// _logger.Info(e.Message);
//}
}
}
return command;
} public System.Data.IDbDataParameter CreateDataParameter()
{
return _dataSource.DbProvider.CreateDataParameter();
}
public System.Data.IDbDataAdapter CreateDataAdapter()
{
return _dataSource.DbProvider.CreateDataAdapter();
}
public System.Data.IDbDataAdapter CreateDataAdapter(System.Data.IDbCommand command)
{
IDbDataAdapter dataAdapter = null;
dataAdapter = _dataSource.DbProvider.CreateDataAdapter();
dataAdapter.SelectCommand = command;
return dataAdapter;
}
public void Dispose()
{
//if (_logger.IsDebugEnabled)
//{
// _logger.Debug("Dispose SqlMapSession");
//}
if (_isTransactionOpen == false)
{
if (_connection.State != ConnectionState.Closed)
{
this.CloseConnection();
}
}
else
{
if (_consistent)
{
this.CommitTransaction();
_isTransactionOpen = false;
}
else
{
if (_connection.State != ConnectionState.Closed)
{
this.RollBackTransaction();
_isTransactionOpen = false;
}
}
}
}
}
}

程序结构如下图:

  3、数据库集群服务

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

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

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

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

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

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

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

  5、插件管理

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

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

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

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

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

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

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

  8、待续.....

  

构建高性能插件式Web框架的更多相关文章

  1. 插件式Web框架

    转载构建高性能插件式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. 用Inferno代替React开发高性能响应式WEB应用

    什么是Inferno Inferno可以看做是React的另一个精简.高性能实现.它的使用方式跟React基本相同,无论是JSX语法.组件的建立.组件的生命周期,还是与Redux或Mobx的配合.路由 ...

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

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

  6. JAVA web 框架集合

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

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

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

  8. Python 常用Web框架的比较

    转载来自:https://www.cnblogs.com/sunshine-1/p/7372934.html 从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OL ...

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

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

随机推荐

  1. js面向切面编程

    Function.prototype.before=function(func){ var _self=this; return function(){  if(func.apply(this,arg ...

  2. pyspider的基本操作

    一.安装 pip install pyspider 1.修改 pyspider/webui/webdav.py 第209行:否则启动会报错 把: 'domaincontroller': NeedAut ...

  3. 剑指offer——面试题8:二叉树的下一个节点

    // 面试题8:二叉树的下一个结点 // 题目:给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点? // 树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针. ...

  4. ssh无密码登录和scp无密码拷贝

    目的:在A主机上无密码登录B主机 方法: A主机生成密钥:ssh-keygen -t rsa 将密钥复制到B主机:cat ~/.ssh/id_rsa.pub | ssh root@B 'cat > ...

  5. 二维vector容器读取txt坐标

    template <class vector> struct HeadLocation{ vector x; vector y; }; vector<HeadLocation< ...

  6. 面向切面编程 (AOP )

    什么是面向切面编程? 面向切面编程就是(AOP --- aspect-oriented programming), 在百科上说: 面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一 ...

  7. Ace教你一步一步做Android新闻客户端(三) JSON数据解析

    对于服务器端来说,返回给客户端的数据格式一般分为html.xml和json这三种格式,现在给大家讲解一下json这个知识点, 1 如何通过json-lib和gson这两个json解析库来对解析我们的j ...

  8. 让C:\Users文件夹放在D盘

    新安装win7 在安装Win7的过程中,要求输入用户名及密码的时候,先不如输入任何信息,按“Shift+F10”呼出DOS窗口,输入以下命令: robocopy "C:\Users" ...

  9. 如何在ThinkPHP中开启调试模式

    1.为什么使用调试模式? 因为调试会在我们的模板页的最后增加一些trace信息. 2.什么是trace信息? 是ThinkPHP为我们提供好的一些包含了系统运行时间.占用内存.加载时间.请求的协议.. ...

  10. bzoj 5305: [Haoi2018]苹果树

    Description Solution \(n\) 个点的二叉树的方案数是 \(n!\) 证明十分显然:新加入的点占掉了 \(1\) 个位置,新加了 \(2\) 个位置,那么多出来一个位置,所以第 ...