每個公司為加快項目的開發效率,都會使用一些成熟的框架或組件,然后在此基礎之上進行開發。YbSoftwareFactory也可復用這些框架和組件,通過二次開發來開發一個代碼生成插件,把大部分和框架有關的公共代碼和組件封裝打包壓縮到項目文件中,而把和具體業務管理有關的需要變化的代碼使用T4模板來生成。然后使用該代碼生成插件來快速生成一個適合自身開發習慣的可立即運行的解決方案來提高開發進度,然后在此基礎之上進行后續代碼的二次開發。
曾經的某公司用戶在使用了YbSoftwareFactory來進行首個項目的輔助開發,原本計划28天的項目編碼任務僅僅只用了3天,這3天的工作量也就是進行個性化的界面呈現調整和統計報表的制作,因為代碼生成插件所生成的解決方案和代碼已經集成了身份認證、權限管理、驗證規則、日志輸出等公共功能以及實體的增、刪、查、改和導出個性化功能,工作效率的提高程度由此可見。
前一篇文章已經介紹了怎樣實現 IPlugInGroupRepository 接口來完成插件組的開發,本章則介紹插件二次開發的最后一項任務,即插件組內各個插件怎樣實現 IPlugInRepository 接口來完成插件的二次開發。
IPlugInRepository的實現類主要的職責就是完成代碼的生成。 首先來看看IPlugInRepository的接口定義:
IPlugInRepository 接口定義
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Yb.PlugIn.Base;
namespace Yb.PlugIn.Base
{
public interface IPlugInRepository
{
/// <summary>
/// 生成進度通知有關的事件
/// </summary>
event EventHandler<NotifyChangedEventArgs> NotifyChanged;
/// // <summary>
/// // 代碼生成插件組,包含相關的一組插件,每個插件可生成不同類型的代碼
/// // </summary>
// IPlugInGroupRepository GroupRepository { get; set; }
/// <summary>
/// 獲取模板信息
/// </summary>
/// <returns></returns>
IEnumerable<TemplateInfo> GetTemplateInfos();
/// <param name="arg"> /// <summary>
/// 生成代碼前的操作,如創建目錄,解壓文件等
/// </summary>
/// <param name="arg"> 1、解壓后的路徑 </param></param>
void BeforeBuild( object arg);
/// <summary>
/// 生成代碼
/// </summary>
/// <param name="arg"> 數據源 </param>
/// <param name="templateInfos"> The template infos. </param>
/// <returns></returns>
IEnumerable<TemplateInfo> BuildCodes( object arg, IEnumerable<TemplateInfo> templateInfos);
/// <summary>
/// 輸出代碼,如寫文件或者顯示等
/// </summary>
/// <param name="outputMode"> 輸出模式,如輸出文件則會依次執行 BeforeBuild,BuildCodes,AfterBuild </param>
/// <param name="beforeBuildArg"> 開始生成代碼前事件 </param>
/// <param name="argument"> 數據源 </param>
/// <param name="templateInfos"> The template infos. </param>
/// <param name="afterBuildArg"> 開始生成代碼后參數 </param>
/// <returns></returns>
IEnumerable<TemplateInfo> BuildCodes( object beforeBuildArg, object argument, IEnumerable<TemplateInfo> templateInfos, object afterBuildArg);
/// <summary>
/// 代碼生成后的任務,如運行數據庫初始化腳本等
/// </summary>
/// <param name="arg"> 1、連接字符串 </param>
void AfterBuild( object arg);
}
}
下面將通過一個Demo來介紹接口下各個方法和屬性的含義。
一、元數據定義
View Code
Description = " 生成Castel數據訪問層,DevExpress界面層代碼的解決方案 ",
DisplayOrder = 1,
ImageUri = " pack://application:,,,/Yb.PlugIn.CastleDevExpress.WebForm;component/Images/WebFormSolution.png ",
LargeImageUri = " pack://application:,,,/Yb.PlugIn.CastleDevExpress.WebForm;component/Images/WebFormSolution.png ",
CodeOutputMode = CodeOutputMode.File)]
[Export(StaticResources.PlugInGroupKey, typeof(IPlugInRepository))]
public class CastleDxWebSolutionPlugInRepository : CastleDxWebPlugInRepositoryBase
Name:將在Ribbion控件中顯示的本插件的名稱
DisplayOrder:顯示順序
ImageUri和LargeImageUri:將顯示的個性化圖標的URI路徑,可參考上篇文章。
CodeOutputMode:代碼生成模式,File和Preview可選,File模式將生成代碼文件,通常用於完整的解決方案的生成。Preview將顯示預覽的代碼窗口,通常用於實體層、數據訪問層、界面層等某一類的代碼生成,生成的代碼可預覽、編輯並輸出到文件。
二、BeforeBuild方法
本方法主要在代碼生成前執行,主要可用於解壓項目文件到指定路徑,如你無這方面的需求可不用重寫,傳入的 arg 參數為文件路徑。以下是某個具體的實現代碼:
BeforeBuild 方法
/// 解壓文件到指定路徑
/// </summary>
/// <param name="arg"> 解壓路徑 </param>
public override void BeforeBuild( object arg)
{
if (arg == null)
{
throw new ArgumentNullException( " arg ", " 參數不能為空 ");
}
var path = arg.ToString();
if ( string.IsNullOrWhiteSpace(path))
{
throw new ArgumentNullException( " arg ", " 解壓路徑不能為空 ");
}
OnNotifyChanged( new NotifyChangedEventArgs(NotifyType.Infomation, " 正在解壓文件,請稍候 "));
// 解壓文件到指定路徑
FileUtility.ExtractFileTo(ZipFileRelativePath,path);
OnNotifyChanged( new NotifyChangedEventArgs(NotifyType.Infomation, " 解壓文件結束 "));
}
三、GetTemplateInfos 方法
本方法返回本插件代碼生成所需的模板信息記錄列表,這些模板對象將供 YbSoftwareFactory 處理,代碼示例如下:
GetTemplateInfos 方法
/// 獲取本插件所需的模板信息
/// </summary>
/// <returns></returns>
public override IEnumerable<TemplateInfo> GetTemplateInfos()
{
var templateInfo = base.GetTemplateInfos();
return templateInfo.Where(c => c.BuildEnable && (c.Tag & StaticResources.SolutionPlugInTemplateTag) > 0);
}
四、BuildCodes 方法
本方法為代碼生成的核心代碼,其中arg參數為一個表信息記錄列表,templateInfos為模板信息,生成后的代碼將保存到模板信息的“ExportContent”字段並返回。
BuildCodes 方法
/// 生成代碼
/// </summary>
/// <param name="arg"></param>
/// <param name="templateInfos"></param>
/// <returns></returns>
public override IEnumerable<TemplateInfo> BuildCodes( object arg, IEnumerable<TemplateInfo> templateInfos)
{
// 參數類型轉換
var tableInfos = BaseInfoUtility.ObjectToTableInfoList(arg).Where(c=>c.IsSelected).ToList();
// 生成結果
var templateList = new List<TemplateInfo>();
_totalCount = tableInfos.Count() * (templateInfos.Count() - 3) + 3;
_currentIndex = 0;
foreach ( var templateInfo in templateInfos)
{
if(!templateInfo.BuildEnable) continue;
// 讀模板信息
templateInfo.TemplateContent = FileUtility.ReadFile(templateInfo.TemplateRelativePath);
// 判斷模板類型,是否每張表都需生成一個模板
if ((templateInfo.Tag & StaticResources.IsTableInfoListOfTemplateArg) == 0)
{
foreach ( var tableInfo in tableInfos)
{
// 復制模板,防止生成后下一個循環被覆蓋
var currentTemplateInfo = (TemplateInfo)templateInfo.Clone();
// 生成代碼
BuildTableInfoCode( " CurrentTable ", templateList, tableInfo, currentTemplateInfo);
}
}
else
{
// 生成 Web.Config 文件
if (templateInfo.ExportFileNameFormatString.Equals( " Web.config ",StringComparison.OrdinalIgnoreCase))
{
// 創建Web.Config代碼
BuildWebConfigCode(templateList, templateInfo, tableInfos);
}
else
{
// 創建如項目文件等需要傳入“表對象集合”為參數的模板代碼
BuildTableInfosCode(templateList, templateInfo, tableInfos);
}
}
}
return templateList;
}
五、AfterBuild方法
AfterBuild方法主要在代碼生成后進行一些后續處理操作,你可利用該方法進行一些任務,如安裝數據庫初始化腳本等,示例代碼如下:
AfterBuild 方法
/// 安裝和權限有關的數據庫腳本
/// </summary>
/// <param name="arg"></param>
public override void AfterBuild( object arg)
{
if (arg == null || string.IsNullOrWhiteSpace(arg.ToString())) return;
var connStr = arg.ToString();
OnNotifyChanged( new NotifyChangedEventArgs(NotifyType.Infomation, " 正在安裝數據庫腳本 "));
try
{
// 執行創建表的腳本文件
ExecuteSqlServerDbScript(connStr);
// 進度通知
OnNotifyChanged( new NotifyChangedEventArgs(NotifyType.Infomation, " 數據庫腳本處理完成 "));
}
catch (Exception er)
{
// 進度通知
OnNotifyChanged( new NotifyChangedEventArgs(NotifyType.Infomation, string.Format( " 數據庫腳本安裝失敗,{0} ",er.Message)));
}
}
六、OnNotifyChanged方法
該方法主要進行事件通知,在界面上顯示滾動條等。
附下載地址:
“Yb.PlugIn.CastleDevExpress.WebForm”插件源碼下載
附“Yb.PlugIn.CastleDevExpress.WebForm”代碼生成插件的Demo數據庫下載
