设计模式在实际业务应用中的介绍之2——业务工厂

在C#中实现的基于工厂模式打造的业务应用案,全部都是干货。

以前一直没有想过写一些东西来把项目中用到的知识点及技术实现做一个归纳整理并分享出来。现在打算逐渐的把项目中的一些东西整理并分享出来,与大家共勉!

工厂模式相比大家都比较清楚了,现在就该模式在实际项目中的应用做一个实例分享。

工厂模式的核心点就是可以依据应用自由组装业务实现,灵活的适应业务变更,极大的增强系统对业务变更的应变能力。


下面就拿实际项目WMS中的一个模块仓库管理来与大家分享,先简单描述下实现思路:

根据需求分析将仓库管理模块进行业务建模,然后抽象出该模块应该具备的功能,
根据抽象结果分别创建该模块的抽象业务类Warehousebiz及该类的实现类Warehousebiz。

1、先看看结构图:

2、定义业务抽象类Warehousebiz,根据业务抽象该模块的应有功能,下面节选4个功能来介绍
1)获取数据库仓库GetWarehouses

2)获取数据库仓库货架GetStorage_racks
3)获取数据库仓库货架区域GetStorage_rack_zones
4)获取绑定记录GetPack_bindingPager

Warehousebiz类定义

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Web;
using System.Web.Caching;

using Entitys.ComonEnti;
using Common;
using FrameCommon;
using Warehouse.Entities;

namespace Warehouse.Biz
{
public abstract class Warehousebiz : System.MarshalByRefObject
{
public DataTable i18nCommonCurrLang = new DataTable(); //通用语言包
public DataTable i18nWarehouseManageri18nLang = new DataTable(); //Somebiz语言包
public SysEnvironmentSerialize envirObj = null; //传递框架环境

public string logpathForDebug = APPConfig.GetAPPConfig().GetConfigValue("logpathForDebug", ""); //调试日志路径
public string isLogpathForDebug = APPConfig.GetAPPConfig().GetConfigValue("isLogpathForDebug", ""); //是否记录调试日志

public string baseXmlPath = APPConfig.GetAPPConfig().GetConfigValue("XmldataPath", "");

public Warehousebiz(SysEnvironmentSerialize _envirObj)
{
string _currlang = _envirObj.I18nCurrLang;
System.Web.Caching.Cache currCache = HttpRuntime.Cache; //当前缓存
string defaultlang = APPConfig.GetAPPConfig().GetConfigValue("currlang", ""); //默认语种
this.envirObj = _envirObj;

#region 通用语言包

DataTable comlangtmp = (DataTable)currCache.Get("i18nCommonCurrLang");
if (comlangtmp != null)
{
if (defaultlang == _currlang)
{
i18nCommonCurrLang = comlangtmp;
}
else
{
string commoni18nLangPath = string.Format(APPConfig.GetAPPConfig().GetConfigValue("Commoni18nLang", ""), _currlang);
i18nCommonCurrLang = BaseServiceUtility.GetI18nLang(commoni18nLangPath);
}
}
else
{
string commoni18nLangPath = string.Format(APPConfig.GetAPPConfig().GetConfigValue("Commoni18nLang", ""), _currlang);
i18nCommonCurrLang = BaseServiceUtility.GetI18nLang(commoni18nLangPath);
}

#endregion

#region Warehouse语言包

DataTable servFrameSecuriylangtmp = (DataTable)currCache.Get("i18nWarehousei18nLang");
if (servFrameSecuriylangtmp != null)
{
if (defaultlang == _currlang)
{
i18nWarehouseManageri18nLang = servFrameSecuriylangtmp;
}
else
{
string WarehouseSomebizi18nLang = string.Format(this.baseXmlPath + APPConfig.GetAPPConfig().GetConfigValue("WarehouseManageri18nLang", ""), _currlang);
i18nWarehouseManageri18nLang = BaseServiceUtility.GetI18nLang(WarehouseSomebizi18nLang);
}
}
else
{
string WarehouseSomebizi18nLang = string.Format(this.baseXmlPath + APPConfig.GetAPPConfig().GetConfigValue("WarehouseManageri18nLang", ""), _currlang);
i18nWarehouseManageri18nLang = BaseServiceUtility.GetI18nLang(WarehouseSomebizi18nLang);
}

#endregion

}

public bool JudgeObjectValue(object obj)
{
if(obj == null)
{
return false;
}
else if((string)obj == string.Empty)
{
return false;
}

return true;
}

/// <summary>
/// 获取数据库仓库
/// </summary>
/// <param name="warehouse"></param>
/// <param name="ddnmParams"></param>
/// <param name="errStr"></param>
/// <param name="ListBizLog"></param>
/// <returns></returns>
public abstract List<WAREHOUSE> GetWarehouses(WAREHOUSE warehouse, DistributeDataNodeManagerParams ddnmParams, List<string> errStr, List<SSY_LOGENTITY> ListBizLog);

/// <summary>
/// 获取数据库仓库货架
/// </summary>
/// <param name="bizobj"></param>
/// <param name="ddnmParams"></param>
/// <param name="errStr"></param>
/// <param name="ListBizLog"></param>
/// <returns></returns>
public abstract List<STORAGE_RACK> GetStorage_racks(STORAGE_RACK bizobj, DistributeDataNodeManagerParams ddnmParams, List<string> errStr, List<SSY_LOGENTITY> ListBizLog);

/// <summary>
/// 获取数据库仓库货架区域
/// </summary>
/// <param name="bizobj"></param>
/// <param name="ddnmParams"></param>
/// <param name="errStr"></param>
/// <param name="ListBizLog"></param>
/// <returns></returns>
public abstract List<STORAGE_RACK_ZONE> GetStorage_rack_zones(STORAGE_RACK_ZONE bizobj, DistributeDataNodeManagerParams ddnmParams, List<string> errStr, List<SSY_LOGENTITY> ListBizLog);

/// <summary>
/// 获取绑定记录
/// </summary>
/// <param name="bizobj"></param>
/// <param name="ddnmParams"></param>
/// <param name="pager"></param>
/// <param name="errStr"></param>
/// <param name="ListBizLog"></param>
/// <returns></returns>
public abstract List<PACK_BINDING> GetPack_bindingPager(PACK_BINDING bizobj, DistributeDataNodeManagerParams ddnmParams, SSY_PagingParam pager, List<string> errStr, List<SSY_LOGENTITY> ListBizLog);


}
}


3、定义业务抽象类Warehousebiz的实现类BizExectuteWarehousebiz,该类基础业务抽象类,并实现上面的4个节选功能
1)获取数据库仓库GetWarehouses

2)获取数据库仓库货架GetStorage_racks
3)获取数据库仓库货架区域GetStorage_rack_zones
4)获取绑定记录GetPack_bindingPager

BizExectuteWarehousebiz类定义

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Reflection;

using Warehouse.Biz;
using Entitys.ComonEnti;
using DataAccessLayer.DataBaseFactory;
using Common;
using FrameCommon;
using Warehouse.Entities;

namespace Warehouse.BizExectute
{
public class BizExectuteWarehousebiz : Warehousebiz
{
public BizExectuteWarehousebiz(SysEnvironmentSerialize _envirObj): base(_envirObj)
{

}

/// <summary>
/// 获取数据库仓库
/// </summary>
/// <param name="warehouse"></param>
/// <param name="ddnmParams"></param>
/// <param name="errStr"></param>
/// <param name="ListBizLog"></param>
/// <returns></returns>
public override List<WAREHOUSE> GetWarehouses(WAREHOUSE warehouse, DistributeDataNodeManagerParams ddnmParams, List<string> errStr, List<SSY_LOGENTITY> ListBizLog)
{
List<WAREHOUSE> listReturn = new List<WAREHOUSE>();
DataSet ds = null;
StringBuilder sbb = new StringBuilder();

try
{
sbb.AppendLine(string.Format(@" select * FROM {0}.WAREHOUSE where 1 = 1 ",
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.DbSchema));

List<IDataParameter> parameters = new List<IDataParameter>();
if (warehouse != null)
{
#region 处理参数

if (base.JudgeObjectValue(warehouse.WH_CODE))
{
sbb.AppendLine(string.Format(@"and WH_CODE = {0}WH_CODE ", DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign()));

parameters.Add(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.GetDataParameter(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign() + "WH_CODE",
DbType.String, warehouse.WH_CODE.ToString()));
}
if (base.JudgeObjectValue(warehouse.WH_NAME))
{
sbb.AppendLine(string.Format(@"and WH_NAME like '%' {0} {1}WH_NAME {0} '%' ",
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ConnectChar(),
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign()));

parameters.Add(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.GetDataParameter(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign() + "WH_NAME",
DbType.String, warehouse.WH_NAME.ToString()));
}

#endregion
}

ds = DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.GetDataSet(sbb.ToString(), SqlExecType.SqlText, parameters.ToArray());

if (Common.Utility.DsHasData(ds))
{
listReturn = Common.UtilitysForT<WAREHOUSE>.GetListsObj(ds.Tables[0]);
}
else
{
errStr.Add(BaseServiceUtility.GetI18nLangItem("noFindData", base.i18nCommonCurrLang));
}
}
catch (Exception ex)
{
errStr.Add(BaseServiceUtility.GetI18nLangItem("findDataErr", base.i18nCommonCurrLang) + ex.Message);
}

return listReturn;
}

/// <summary>
/// 获取数据库仓库货架
/// </summary>
/// <param name="bizobj"></param>
/// <param name="ddnmParams"></param>
/// <param name="errStr"></param>
/// <param name="ListBizLog"></param>
/// <returns></returns>
public override List<STORAGE_RACK> GetStorage_racks(STORAGE_RACK bizobj, DistributeDataNodeManagerParams ddnmParams, List<string> errStr, List<SSY_LOGENTITY> ListBizLog)
{
List<STORAGE_RACK> listReturn = new List<STORAGE_RACK>();
DataSet ds = null;
StringBuilder sbb = new StringBuilder();

try
{
sbb.AppendLine(string.Format(@" select * FROM {0}.STORAGE_RACK where 1 = 1 ",
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.DbSchema));

List<IDataParameter> parameters = new List<IDataParameter>();
if (bizobj != null)
{
#region 处理参数

if (base.JudgeObjectValue(bizobj.SR_CODE))
{
sbb.AppendLine(string.Format(@"and SR_CODE = {0}SR_CODE ", DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign()));

parameters.Add(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.GetDataParameter(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign() +
"SR_CODE", DbType.String, bizobj.SR_CODE.ToString()));
}
if (base.JudgeObjectValue(bizobj.WH_ID))
{
sbb.AppendLine(string.Format(@"and WH_ID = {0}WH_ID ", DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign()));

parameters.Add(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.GetDataParameter(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign() +
"WH_ID", DbType.String, bizobj.WH_ID.ToString()));
}
if (base.JudgeObjectValue(bizobj.SR_NAME))
{
sbb.AppendLine(string.Format(@"and SR_NAME like '%' {0} {1}SR_NAME {0} '%' ",
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ConnectChar(),
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign()));

parameters.Add(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.GetDataParameter(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign() +
"SR_NAME", DbType.String, bizobj.SR_NAME.ToString()));
}

#endregion
}

ds = DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.GetDataSet(sbb.ToString(), SqlExecType.SqlText, parameters.ToArray());

if (Common.Utility.DsHasData(ds))
{
listReturn = Common.UtilitysForT<STORAGE_RACK>.GetListsObj(ds.Tables[0]);
}
else
{
errStr.Add(BaseServiceUtility.GetI18nLangItem("noFindData", base.i18nCommonCurrLang));
}
}
catch (Exception ex)
{
errStr.Add(BaseServiceUtility.GetI18nLangItem("findDataErr", base.i18nCommonCurrLang) + ex.Message);
}

return listReturn;
}

 

/// <summary>
/// 获取数据库仓库货架区域
/// </summary>
/// <param name="bizobj"></param>
/// <param name="ddnmParams"></param>
/// <param name="errStr"></param>
/// <param name="ListBizLog"></param>
/// <returns></returns>
public override List<STORAGE_RACK_ZONE> GetStorage_rack_zones(STORAGE_RACK_ZONE bizobj, DistributeDataNodeManagerParams ddnmParams, List<string> errStr, List<SSY_LOGENTITY> ListBizLog)
{
List<STORAGE_RACK_ZONE> listReturn = new List<STORAGE_RACK_ZONE>();
DataSet ds = null;
StringBuilder sbb = new StringBuilder();

try
{
sbb.AppendLine(string.Format(@" select * FROM {0}.STORAGE_RACK_ZONE where 1 = 1 ",
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.DbSchema));

List<IDataParameter> parameters = new List<IDataParameter>();
if (bizobj != null)
{
#region 处理参数

if (base.JudgeObjectValue(bizobj.SRZ_CODE))
{
sbb.AppendLine(string.Format(@"and SRZ_CODE = {0}SRZ_CODE ", DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign()));

parameters.Add(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.GetDataParameter(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign() +
"SRZ_CODE", DbType.String, bizobj.SRZ_CODE.ToString()));
}
if (base.JudgeObjectValue(bizobj.SR_ID))
{
sbb.AppendLine(string.Format(@"and SR_ID = {0}SR_ID ", DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign()));

parameters.Add(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.GetDataParameter(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign() +
"SR_ID", DbType.String, bizobj.SR_ID.ToString()));
}
if (base.JudgeObjectValue(bizobj.SRZ_NAME))
{
sbb.AppendLine(string.Format(@"and SRZ_NAME like '%' {0} {1}SRZ_NAME {0} '%' ",
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ConnectChar(),
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign()));

parameters.Add(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.GetDataParameter(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign() +
"SRZ_NAME", DbType.String, bizobj.SRZ_NAME.ToString()));
}

#endregion
}

ds = DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.GetDataSet(sbb.ToString(), SqlExecType.SqlText, parameters.ToArray());

if (Common.Utility.DsHasData(ds))
{
listReturn = Common.UtilitysForT<STORAGE_RACK_ZONE>.GetListsObj(ds.Tables[0]);
}
else
{
errStr.Add(BaseServiceUtility.GetI18nLangItem("noFindData", base.i18nCommonCurrLang));
}
}
catch (Exception ex)
{
errStr.Add(BaseServiceUtility.GetI18nLangItem("findDataErr", base.i18nCommonCurrLang) + ex.Message);
}

return listReturn;
}


/// <summary>
/// 获取绑定记录
/// </summary>
/// <param name="bizobj"></param>
/// <param name="ddnmParams"></param>
/// <param name="pager"></param>
/// <param name="errStr"></param>
/// <param name="ListBizLog"></param>
/// <returns></returns>
public override List<PACK_BINDING> GetPack_bindingPager(PACK_BINDING bizobj, DistributeDataNodeManagerParams ddnmParams, SSY_PagingParam pager, List<string> errStr, List<SSY_LOGENTITY> ListBizLog)
{
List<PACK_BINDING> listReturn = new List<PACK_BINDING>();

//分页数据获取实现
//分页参数数据
SSY_PagingExecuteParam pageExecute = new SSY_PagingExecuteParam();
pageExecute.PagingParam = pager;

//参数值,若有,增加到该集合
List<IDataParameter> parameters = new List<IDataParameter>();
StringBuilder sbbSqlWhere = new StringBuilder();
if (bizobj != null)
{
if (Utility.ObjHasData(bizobj.PACK_TYPE))
{
sbbSqlWhere.AppendLine(string.Format(@"and PACK_TYPE = {0}PACK_TYPE ",
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign()));
parameters.Add(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.
GetDataParameter("PACK_TYPE",
DbType.String, bizobj.PACK_TYPE.ToString()));
}
if (Utility.ObjHasData(bizobj.BOX_NO))
{
sbbSqlWhere.AppendLine(string.Format(@"and BOX_NO = {0}BOX_NO ",
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign()));
parameters.Add(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.
GetDataParameter("BOX_NO",
DbType.String, bizobj.BOX_NO.ToString()));
}
if (Utility.ObjHasData(bizobj.TRACE_NO))
{
sbbSqlWhere.AppendLine(string.Format(@"and TRACE_NO = {0}TRACE_NO ",
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign()));
parameters.Add(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.
GetDataParameter("TRACE_NO",
DbType.String, bizobj.TRACE_NO.ToString()));
}

if (Utility.ObjHasData(bizobj.IN_WH_CODE))
{
sbbSqlWhere.AppendLine(string.Format(@"and IN_WH_CODE = {0}IN_WH_CODE ",
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign()));
parameters.Add(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.
GetDataParameter("IN_WH_CODE",
DbType.String, bizobj.IN_WH_CODE.ToString()));
}

if (Utility.ObjHasData(bizobj.IN_SR_CODE))
{
sbbSqlWhere.AppendLine(string.Format(@"and IN_SR_CODE = {0}IN_SR_CODE ",
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign()));
parameters.Add(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.
GetDataParameter("IN_SR_CODE",
DbType.String, bizobj.IN_SR_CODE.ToString()));
}
if (Utility.ObjHasData(bizobj.IN_SRZ_CODE))
{
sbbSqlWhere.AppendLine(string.Format(@"and IN_SRZ_CODE = {0}IN_SRZ_CODE ",
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.ParamSign()));
parameters.Add(DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.
GetDataParameter("IN_SRZ_CODE",
DbType.String, bizobj.IN_SRZ_CODE.ToString()));
}
}

pageExecute.TableNameOrView = string.Format(@" {0}.PACK_BINDING ",
DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.DbSchema);

//pageExecute.Joins = string.Empty;
pageExecute.Joins = " left join (select optioniden, optionnames as pack_type_name from ssy_biz_dict where domainnameiden = 'Pack_Type') on pack_type = optioniden ";
pageExecute.Fields = "*";
pageExecute.OrderField = "BIND_NO";
pageExecute.SqlWhere = " 1=1 " + sbbSqlWhere.ToString();

StringBuilder sbbSql = new StringBuilder();
if (pager.TotalSize == 0)
{
//首次计算总记录
sbbSql.Clear();
if (string.IsNullOrEmpty(pageExecute.SqlWhere))
{
sbbSql.Append(string.Format(@"SELECT count(*) as cnt FROM {0} {1} ", pageExecute.TableNameOrView, pageExecute.Joins));
}
else
{
sbbSql.Append(string.Format(@"SELECT count(*) as cnt FROM {0} {1} where {2} ", pageExecute.TableNameOrView, pageExecute.Joins,
pageExecute.SqlWhere));
}

DataTable dt = DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.GetDataTable(sbbSql.ToString(),
SqlExecType.SqlText, parameters.ToArray());

if (Utility.DtHasData(dt))
{
pager.TotalSize = int.Parse(dt.Rows[0]["cnt"].ToString());
}
}

DataTable dtTmp = DBFactorySingleton.GetInstance(ddnmParams.DistributeDataNode).Factory.GetDataPager(pageExecute, parameters.ToArray());

if (Common.Utility.DtHasData(dtTmp))
{
listReturn = Common.UtilitysForT<PACK_BINDING>.GetListsObj(dtTmp);
}
else
{
errStr.Add(BaseServiceUtility.GetI18nLangItem("noFindData", base.i18nCommonCurrLang));
}

return listReturn;
}


 

#region 私有方法

/// <summary>
/// 判读库位当前状态
/// </summary>
/// <param name="listReturn"></param>
/// <param name="drPosition"></param>
/// <returns></returns>
private string JudgePositionState(List<PACK_BINDING> listReturn, DataRow drPosition)
{
StringBuilder sbb = new StringBuilder();
if(drPosition["srzp_isuse"].ToString() == "0")
{
sbb.Append("禁用|fa fa-times|divnouse|");
}
else
{
bool hasPosition = false;
string pack_type_name = string.Empty;
string box_no = string.Empty;
for (int i = 0; i < listReturn.Count; i++)
{
if(drPosition["srzp_code"].ToString() == listReturn[i].IN_SRZP_CODE.ToString())
{
hasPosition = true;
pack_type_name = listReturn[i].PACK_TYPE_NAME.ToString();
box_no = listReturn[i].BOX_NO.ToString();
break;
}
}
if (hasPosition)
{
sbb.Append(pack_type_name + "|fa fa-align-justify|divuse|" + box_no);
}
else
{
sbb.Append("空货位|fa fa-square-o|divuseempty|");
}
}

return sbb.ToString();
}

#endregion

 

}
}


4、定义普通业务工厂类BizFactoryWarehouse,负责装配业务类
BizFactoryWarehouse类定义

public class BizFactoryWarehouse
{
public Warehousebiz Create(string bizType, SysEnvironmentSerialize _envirObj)
{
if (bizType == "one")
{
//return new BizExectuteCommon();
return AOPFactory.Create<BizExectuteWarehousebiz>(new BizExectuteWarehousebiz(_envirObj));
}
return null;
}
}

5、定义泛型业务工厂类BizFactoryWarehouse<T>,该类和普通工厂类干一样的事情,只是泛型可以支持多种类型,这里支持业务类变更类型
具体使用普通业务工厂还是泛型业务工厂,完全取决于应用需求
BizFactoryWarehouse<T>类定义

/// <summary>
/// 泛型工厂
/// </summary>
/// <typeparam name="T"></typeparam>
public class BizFactoryWarehouse<T>
{
public T Create(string bizType, SysEnvironmentSerialize _envirObj)
{
return (T)this.GetBiz(bizType, _envirObj);
}

public object GetBiz(string bizType, SysEnvironmentSerialize _envirObj)
{
if (bizType == "one")
{
return AOPFactory.Create<BizExectuteWarehousebiz>(new BizExectuteWarehousebiz(_envirObj));
}
return null;
}
}

6、定义AOP模式工厂类AOPFactory,负责横切(也有的叫劫持)业务类
AOPFactory类定义

public static class AOPFactory
{
public static T Create<T>(T target)
{
DueWithAOP<T> dwAOP = new DueWithAOP<T>(target);
return (T)(dwAOP.GetTransparentProxy());
}
}

7、定义AOP模式处理类DueWithAOP<T>,AOPFactory类需要依赖DueWithAOP<T>处理类,该类负责横切业务类,同时执行权限验证、日志记录等同用功能
DueWithAOP<T>类定义

public class DueWithAOP<T> : RealProxy
{
public string logpathForDebug = APPConfig.GetAPPConfig().GetConfigValue("logpathForDebug", ""); //调试日志路径
public string isLogpathForDebug = APPConfig.GetAPPConfig().GetConfigValue("isLogpathForDebug", ""); //是否记录调试日志

public T Target
{
get; internal set;
}

public DueWithAOP(T target) : base(typeof(T))
{
this.Target = target;
}

public override IMessage Invoke(IMessage msg)
{
#region 日志准备

List<string> opObjPerporty = UtilitysForT<SSY_LOGENTITY>.GetAllColumns(new SSY_LOGENTITY()); //要操作的属性名
List<string> opWherePerporty = new List<string>(); //where条件属性名
opWherePerporty.Add("LOGID");
List<string> mainProperty = new List<string>(); //主键属性名
mainProperty.Add("LOGID");

//string errStr = string.Empty;
List<string> errStr = new List<string>();
List<SSY_LOGENTITY> opList = new List<SSY_LOGENTITY>();
SSY_LOGENTITY logenti = null;

BizExectuteCommon recordLog = new BizExectuteCommon(ManagerSysEnvironment.GetSysEnvironmentSerialize()); //其他工厂记录日志也利用该公共方法

//日志固定部分
string USERNAMES = string.Empty;
if (FrameCommon.SysEnvironment.SysUserDict != null)
{
if (FrameCommon.SysEnvironment.SysUserDict.USERNAME != null)
{
USERNAMES = FrameCommon.SysEnvironment.SysUserDict.USERNAME.ToString();
}
}
string IPS = string.Empty;
if (!string.IsNullOrEmpty(FrameCommon.SysEnvironment.Ips))
{
IPS = FrameCommon.SysEnvironment.Ips;
}
string SYSTEMNAME = string.Empty;
if (!string.IsNullOrEmpty(FrameCommon.SysEnvironment.distManagerParam.DistributeDataNodes[0].Systemname))
{
SYSTEMNAME = FrameCommon.SysEnvironment.distManagerParam.DistributeDataNodes[0].Systemname;
}

#endregion

IMethodCallMessage mcall = (IMethodCallMessage)msg; //劫持方法,准备执行
var resResult = new ReturnMessage(new Exception(), mcall);

#region 获取必要参数

//distributeActionIden 分布式动作识别, 必须存在
//distributeDataNodes 分布式数据节点集合, 必须存在
//distributeDataNode 分布式数据节点参数, 必须存在
//distriActionSql 分布式操作sql集合,必须存在,包括sql正文和参数
//ddnmParams

//singleActionList 单点操作失败集合, out参数 非必须存在,传入空的参数即可

//TODO 检查必须的参数,若不存在不进行执行业务方法,返回执行异常

//获取分布式管理参数
DistributeDataNodeManagerParams distManagerParam = new DistributeDataNodeManagerParams();
for (int i = 0; i < mcall.InArgs.Length; i++)
{
if (mcall.GetInArgName(i).ToUpper() == "ddnmParams".ToUpper())
{
distManagerParam = ((DistributeDataNodeManagerParams)mcall.GetInArg(i));
//SYSTEMNAME = distManagerParam.DistributeDataNodes[0].Systemname;
break;
}
}

//获取分布式动作识别参数
DistributeActionIden distBAC = distManagerParam.DistributeActionIden;

//加载数据节点集合,然后根据节点数量及分布式动作识别初始化分布式数据节点及分布式事务处理
//数据节点集合由服务方法传入
//获取数据节点集合参数
List<SSY_DATANODE_ADDR> dataNodes = distManagerParam.DistributeDataNodes;

//获取数据节点参数
DistributeDataNode ddn = distManagerParam.DistributeDataNode;

//单点操作失败集合,最后要报告给节点中心,out参数
bool permitSingleDataOperation = false; //是否支持单点操作失败后进行报告
List<SSY_DATA_ACTION_TASK> data_action_task = new List<SSY_DATA_ACTION_TASK>();
for (int i = 0; i < mcall.InArgs.Length; i++)
{
if (mcall.GetInArgName(i).ToUpper() == "singleActionList".ToUpper())
{
permitSingleDataOperation = true;
data_action_task = mcall.GetInArg(i) as List<SSY_DATA_ACTION_TASK>;
break;
}
}

#endregion

if (distBAC == DistributeActionIden.Query)
{
//处理数据节点
//distManagerParam.DistributeDataNode
distManagerParam.DistributeDataNode.Connectionstring = string.Format(dataNodes[0].Data_conn, dataNodes[0].Url_addr,
dataNodes[0].Data_user, dataNodes[0].Data_password);
distManagerParam.DistributeDataNode.DbSchema = dataNodes[0].Data_schema;

//只执行一次即可
#region 执行业务方法

try
{
object objRv = mcall.MethodBase.Invoke(this.Target, mcall.Args);

#region 记录业务日志

//执行方法后记录正常业务日志,内容来自方法ListBizLog参数
//若要记录日志,要求该方法必须传入该参数,且名字必须为ListBizLog,内容为要记录的业务日志内容
SSY_LOGENTITY tempLog = null;
for (int i = 0; i < mcall.InArgs.Length; i++)
{
if (mcall.GetInArgName(i).ToUpper() == "ListBizLog".ToUpper())
{
List<SSY_LOGENTITY> dictBizLog = mcall.GetInArg(i) as List<SSY_LOGENTITY>;

for (int j = 0; j < dictBizLog.Count; j++)
{
//遍历记录业务日志
tempLog = dictBizLog[j] as SSY_LOGENTITY;

//获取日志控制,确定是否记录该类日志
if (recordLog.CheckIsRecord(tempLog.DOMAINNAME.ToString(), tempLog.OPTIONNAME.ToString(), distManagerParam))
{
tempLog.LOGID = recordLog.GetID(MakeIDType.YMDHMS_3, string.Empty, null, distManagerParam);

//业务直接使用业务端提交的数据,不在读取框架环境变量,因为登录时这部分数据滞后,导致不能记入日志
//tempLog.USERNAMES = USERNAMES;
//tempLog.IPS = IPS;
//tempLog.SYSTEMNAME = SYSTEMNAME;

opList.Add(tempLog);
}
}
if (opList.Count > 0)
{
//记录日志
bool flag = recordLog.OpBizObjectSingle<SSY_LOGENTITY>(opList, opObjPerporty, opWherePerporty, mainProperty, errStr, distManagerParam);
}
break;
}
}

#endregion

resResult = new ReturnMessage(objRv, mcall.Args, mcall.Args.Length, mcall.LogicalCallContext, mcall);
}
catch (Exception ex)
{
Common.Utility.RecordLog("工厂 Query 模式发生异常!原因" + ex.Message + ex.Source, this.logpathForDebug, this.isLogpathForDebug);

#region 记录异常日志

if (ex.InnerException != null)
{
//获取日志控制,确定是否记录该类日志
if (recordLog.CheckIsRecord("ExceptionErr", "ExceptionErr", distManagerParam))
{
//处理异常类相关信息
string CLASSNAME = mcall.TypeName;
string METHORDNAME = mcall.MethodName;

//异常时这部分可没有内容
string TABLENAME = "";
string RECORDIDENCOLS = "";
string RECORDIDENCOLSVALUES = "";
string FUNCTIONNAME = "";

logenti = LogCommon.CreateLogDataEnt(LogTypeDomain.ExceptionErr, LogLevelOption.ExecptionErr, recordLog.GetSystemDateTime(distManagerParam),
CLASSNAME, METHORDNAME, LogAction.ExecptionErr, TABLENAME, RECORDIDENCOLS, RECORDIDENCOLSVALUES, USERNAMES, IPS, FUNCTIONNAME,
ex.InnerException.Message, SYSTEMNAME, "");
logenti.LOGID = recordLog.GetID(MakeIDType.YMDHMS_3, string.Empty, null, distManagerParam);

opList.Add(logenti);

if (opList.Count > 0)
{
//记录日志
bool flag = recordLog.OpBizObjectSingle<SSY_LOGENTITY>(opList, opObjPerporty, opWherePerporty, mainProperty, errStr, distManagerParam);
}
}

resResult = new ReturnMessage(ex.InnerException, mcall);
}

#endregion

resResult = new ReturnMessage(ex, mcall);
}

#endregion
}
else if (distBAC == DistributeActionIden.SingleAction)
{
//数据节点有几个执行几次,单次提交,发现执行异常,将异常报告给节点中心,继续执行,直到完毕
for (int m = 0; m < dataNodes.Count; m++)
{
//ddn.DbFactoryName 数据库工厂取配置文件,目前不考虑同构不同种类的数据库
distManagerParam.DistributeDataNode.Connectionstring = string.Format(dataNodes[m].Data_conn, dataNodes[m].Url_addr, dataNodes[m].Data_user,
dataNodes[m].Data_password);
distManagerParam.DistributeDataNode.DbSchema = dataNodes[m].Data_schema;

#region 执行业务方法

try
{
object objRv = mcall.MethodBase.Invoke(this.Target, mcall.Args);

#region 记录业务日志

//执行方法后记录正常业务日志,内容来自方法ListBizLog参数
//若要记录日志,要求该方法必须传入该参数,且名字必须为ListBizLog,内容为要记录的业务日志内容
SSY_LOGENTITY tempLog = null;
for (int i = 0; i < mcall.InArgs.Length; i++)
{
if (mcall.GetInArgName(i).ToUpper() == "ListBizLog".ToUpper())
{
List<SSY_LOGENTITY> dictBizLog = mcall.GetInArg(i) as List<SSY_LOGENTITY>;

for (int j = 0; j < dictBizLog.Count; j++)
{
//遍历记录业务日志
tempLog = dictBizLog[j] as SSY_LOGENTITY;

//获取日志控制,确定是否记录该类日志
if (recordLog.CheckIsRecord(tempLog.DOMAINNAME.ToString(), tempLog.OPTIONNAME.ToString(), distManagerParam))
{
tempLog.LOGID = recordLog.GetID(MakeIDType.YMDHMS_3, string.Empty, null, distManagerParam);

//业务直接使用业务端提交的数据,不在读取框架环境变量,因为登录时这部分数据滞后,导致不能记入日志
//tempLog.USERNAMES = USERNAMES;
//tempLog.IPS = IPS;
//tempLog.SYSTEMNAME = SYSTEMNAME;

opList.Add(tempLog);
}
}
if (opList.Count > 0)
{
//记录日志
bool flag = recordLog.OpBizObjectSingle<SSY_LOGENTITY>(opList, opObjPerporty, opWherePerporty, mainProperty, errStr, distManagerParam);
}
break;
}
}

#endregion

resResult = new ReturnMessage(objRv, mcall.Args, mcall.Args.Length, mcall.LogicalCallContext, mcall);
}
catch (Exception ex)
{
Common.Utility.RecordLog("工厂 SingleAction 模式发生异常!原因" + ex.Message + ex.Source, this.logpathForDebug, this.isLogpathForDebug);

SSY_DATA_ACTION_TASK tempDataTask = null;

#region 记录异常日志

if (ex.InnerException != null)
{
//获取日志控制,确定是否记录该类日志
if (recordLog.CheckIsRecord("ExceptionErr", "ExceptionErr", distManagerParam))
{
//处理异常类相关信息
string CLASSNAME = mcall.TypeName;
string METHORDNAME = mcall.MethodName;

//异常时这部分可没有内容
string TABLENAME = "";
string RECORDIDENCOLS = "";
string RECORDIDENCOLSVALUES = "";
string FUNCTIONNAME = "";

logenti = LogCommon.CreateLogDataEnt(LogTypeDomain.ExceptionErr, LogLevelOption.ExecptionErr, recordLog.GetSystemDateTime(distManagerParam),
CLASSNAME, METHORDNAME, LogAction.ExecptionErr, TABLENAME, RECORDIDENCOLS, RECORDIDENCOLSVALUES, USERNAMES, IPS, FUNCTIONNAME,
ex.InnerException.Message, SYSTEMNAME, "");
logenti.LOGID = recordLog.GetID(MakeIDType.YMDHMS_3, string.Empty, null, distManagerParam);

opList.Add(logenti);

if (opList.Count > 0)
{
//记录日志
bool flag = recordLog.OpBizObjectSingle<SSY_LOGENTITY>(opList, opObjPerporty, opWherePerporty, mainProperty, errStr, distManagerParam);
}
}
if (permitSingleDataOperation)
{
#region 获取失败操作sql

//获取失败记录,以便将任务报告给节点中心
//获取操作sql List<DistActionSql> DistriActionSqlParams

for (int task = 0; task < distManagerParam.DistriActionSqlParams.Count; task++)
{
tempDataTask = new SSY_DATA_ACTION_TASK();
tempDataTask.Action_sql = distManagerParam.DistriActionSqlParams[task].ActionSqlText;
string tempSqlParamSeq = string.Empty;
bool temddddd = JsonSerializer.Serialize(distManagerParam.DistriActionSqlParams[task].ActionSqlTextParams, out tempSqlParamSeq);
//保存sql参数序列化结果
tempDataTask.Action_sql_params = tempSqlParamSeq;
tempDataTask.Data_real_conn = ddn.Connectionstring;
data_action_task.Add(tempDataTask);
}
//执行完毕后,清除本次的sql记录
distManagerParam.DistriActionSqlParams.Clear();

//TODO 报告单点异常给节点中心,暂时不支持,后续扩展
#endregion
}
}

#endregion

continue; //继续执行
}

#endregion
}
}
else if (distBAC == DistributeActionIden.TransAction)
{
try
{
//分布式事务执行, 按数据节点数量执行,同步提交
using (var ts = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, TimeSpan.FromHours(1)))
{
for (int m = 0; m < dataNodes.Count; m++)
{
//ddn.DbFactoryName 数据库工厂取配置文件,目前不考虑同构不同种类的数据库
distManagerParam.DistributeDataNode.Connectionstring = string.Format(dataNodes[m].Data_conn, dataNodes[m].Url_addr, dataNodes[m].Data_user,
dataNodes[m].Data_password);
distManagerParam.DistributeDataNode.DbSchema = dataNodes[m].Data_schema;

#region 执行业务方法

object objRv = mcall.MethodBase.Invoke(this.Target, mcall.Args);

#region 记录业务日志

//执行方法后记录正常业务日志,内容来自方法ListBizLog参数
//若要记录日志,要求该方法必须传入该参数,且名字必须为ListBizLog,内容为要记录的业务日志内容
SSY_LOGENTITY tempLog = null;
for (int i = 0; i < mcall.InArgs.Length; i++)
{
if (mcall.GetInArgName(i).ToUpper() == "ListBizLog".ToUpper())
{
List<SSY_LOGENTITY> dictBizLog = mcall.GetInArg(i) as List<SSY_LOGENTITY>;

for (int j = 0; j < dictBizLog.Count; j++)
{
//遍历记录业务日志
tempLog = dictBizLog[j] as SSY_LOGENTITY;

//获取日志控制,确定是否记录该类日志
if (recordLog.CheckIsRecord(tempLog.DOMAINNAME.ToString(), tempLog.OPTIONNAME.ToString(), distManagerParam))
{
tempLog.LOGID = recordLog.GetID(MakeIDType.YMDHMS_3, string.Empty, null, distManagerParam);

//业务直接使用业务端提交的数据,不在读取框架环境变量,因为登录时这部分数据滞后,导致不能记入日志
//tempLog.USERNAMES = USERNAMES;
//tempLog.IPS = IPS;
//tempLog.SYSTEMNAME = SYSTEMNAME;

opList.Add(tempLog);
}
}
//这里事物不能同时记录日志,需要放到业务方法提交完成后单独记录日志
if (opList.Count > 0)
{
//记录日志
//bool flag = recordLog.OpBizObjectSingle<SSY_LOGENTITY>(opList, opObjPerporty, opWherePerporty, mainProperty, ref errStr, distManagerParam);

}
break;
}
}

#endregion

resResult = new ReturnMessage(objRv, mcall.Args, mcall.Args.Length, mcall.LogicalCallContext, mcall);

#endregion
}

ts.Complete();
ts.Dispose();
}

//恢复事物默认标识
distManagerParam.DistributeActionIden = DistributeActionIden.Query;
//启用事物日志需要独立记录,不能和业务操作混在一个事物里
for (int m = 0; m < dataNodes.Count; m++)
{
//ddn.DbFactoryName 数据库工厂取配置文件,目前不考虑同构不同种类的数据库
distManagerParam.DistributeDataNode.Connectionstring = string.Format(dataNodes[m].Data_conn, dataNodes[m].Url_addr, dataNodes[m].Data_user,
dataNodes[m].Data_password);
distManagerParam.DistributeDataNode.DbSchema = dataNodes[m].Data_schema;

if (opList.Count > 0)
{
//记录日志
bool flag = recordLog.OpBizObjectSingle<SSY_LOGENTITY>(opList, opObjPerporty, opWherePerporty, mainProperty, errStr, distManagerParam);

}
}
}
catch (Exception ex)
{
Common.Utility.RecordLog("工厂 TransAction 模式发生异常!原因" + ex.Message + ex.Source, this.logpathForDebug, this.isLogpathForDebug);
}

}

//最终返回结果
return resResult;
}
}

 

 

获取实例源码请入QQ群706224870,在群文件中下载。

posted on 2018-06-04 08:56  猫头007  阅读(499)  评论(0编辑  收藏  举报

导航