设计模式在实际业务应用中的介绍之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,在群文件中下載。
轉載于:https://www.cnblogs.com/maotou/p/factory.html
總結
以上是生活随笔為你收集整理的设计模式在实际业务应用中的介绍之2——业务工厂的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux中基于eBPF的恶意利用与检测
- 下一篇: Vue计算属性的使用