YbSoftwareFactory 的最新插件,面向WPF的解決方案,具有令人震撼、超級絢麗的界面效果。把該插件的dll文件及相關的模板文件、壓縮文件放到Plugin文件夾下即可在 YbSoftwareFactory 的主應用程序中識別並運行。
本插件在YbSoftwareFactory中的界面效果如下,可單獨生成實體層代碼、MVVM層代碼、WPF層代碼及完整的可直接在VS中調試運行的解決方案:
本插件主要包含如下代碼文件:
其中CastleDxWpfPluginRepositoryBase為本插件的核心類,主要代碼如下:

using System.Collections.Generic;
using System.Linq;
using System.Text;
using Yb.CustomTemplating;
using Yb.DbSchemaReader.DataSchema;
using Yb.Plugin.Base;
using Yb.Utility;
namespace Yb.Plugin.CastleDevExpress.Wpf
{
public abstract class CastleDxWpfPluginRepositoryBase : PluginRepositoryBase
{
private int _totalCount = 0;
private int _currentIndex = 0;
protected virtual int GetShouldBuildCodeNum( int listCount)
{
var templateCount = GetTemplateInfos().Count();
return listCount * (templateCount);
}
/// <summary>
/// 生成代碼
/// </summary>
/// <param name="dataSource"></param>
/// <param name="templateInfos"></param>
/// <returns></returns>
public override IEnumerable<TemplateInfo> BuildCodes( object dataSource, IEnumerable<TemplateInfo> templateInfos, object dataSourceInfo)
{
// 參數類型轉換
var tableInfos = BaseInfoUtility.ObjectToDatabaseTableList(dataSource).Where(c => c.Checked).ToList();
// 生成結果
var templateList = new List<TemplateInfo>();
_totalCount = GetShouldBuildCodeNum(tableInfos.Count);
_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();
// 生成代碼
BuildTableCode( " CurrentTable ", templateList, tableInfo, currentTemplateInfo);
}
}
else
{
// 生成 App.Config 文件
if (templateInfo.ExportFileNameFormatString.Equals( " App.config ", StringComparison.OrdinalIgnoreCase))
{
var sourceInfo = dataSourceInfo as DataSourceInfo;
// 創建Web.Config代碼
if (sourceInfo != null)
BuildAppConfigCode(templateList, templateInfo, tableInfos, sourceInfo);
} else
{
// 創建如項目文件等需要傳入“表對象集合”為參數的模板代碼
BuildTablesCode(templateList, templateInfo, tableInfos);
}
}
}
return templateList;
}
/// <summary>
/// 創建和表有關的代碼
/// </summary>
/// <param name="templateArgName"></param>
/// <param name="templateList"></param>
/// <param name="tableInfo"></param>
/// <param name="templateInfo"></param>
private void BuildTableCode( string templateArgName, List<TemplateInfo> templateList, DatabaseTable tableInfo, TemplateInfo templateInfo)
{
try
{
// 代碼生成關鍵代碼,根據模板生成代碼
templateInfo.ExportContent = Template.Transform(templateInfo.TemplateContent, templateArgName,
tableInfo);
// 更新模板標題,標題也是要生成文件的名稱
templateInfo.Title = BaseInfoUtility.ReplaceString(templateInfo.ExportFileNameFormatString,
tableInfo.Name);
templateInfo.ExportRelativePath = BaseInfoUtility.ReplaceString(templateInfo.ExportRelativePathFormatString,
tableInfo.Name);
AddCodeList(templateList, templateInfo);
}
catch (Exception er)
{
NotifyException(templateInfo, er);
}
}
/// <summary>
/// 創建和數據庫有關的代碼
/// </summary>
/// <param name="templateList"></param>
/// <param name="templateInfo"></param>
/// <param name="tableInfos"></param>
private void BuildTablesCode(List<TemplateInfo> templateList, TemplateInfo templateInfo, List<DatabaseTable> tableInfos)
{
try
{
templateInfo.ExportContent = Template.Transform(templateInfo.TemplateContent, " TableInfos ",
tableInfos);
templateInfo.Title = templateInfo.ExportFileNameFormatString;
templateInfo.ExportRelativePath = templateInfo.ExportRelativePathFormatString;
AddCodeList(templateList, templateInfo);
}
catch (Exception er)
{
NotifyException(templateInfo, er);
}
}
/// <summary>
/// 創建Web.Config 代碼
/// </summary>
/// <param name="templateList"></param>
/// <param name="templateInfo"></param>
/// <param name="tableInfos"></param>
private void BuildAppConfigCode(List<TemplateInfo> templateList, TemplateInfo templateInfo, List<DatabaseTable> tableInfos, DataSourceInfo dataSourceInfo)
{
try
{
templateInfo.ExportContent = Template.Transform(templateInfo.TemplateContent, " DataSourceInfo ",
dataSourceInfo);
templateInfo.Title = templateInfo.ExportFileNameFormatString;
templateInfo.ExportRelativePath = templateInfo.ExportRelativePathFormatString;
AddCodeList(templateList, templateInfo);
}
catch (Exception er)
{
NotifyException(templateInfo, er);
}
}
/// <summary>
/// 代碼創建后進行事件通知
/// </summary>
/// <param name="templateList"></param>
/// <param name="templateInfo"></param>
private void AddCodeList(List<TemplateInfo> templateList, TemplateInfo templateInfo)
{
templateList.Add(templateInfo);
_currentIndex++;
OnNotifyChanged( new NotifyChangedEventArgs(NotifyType.Seccessful,
string.Format( " 代碼 {0} 生成成功 ", templateInfo.Title)
, _currentIndex, _totalCount));
}
/// <summary>
/// 通知代碼創建失敗
/// </summary>
/// <param name="templateInfo"></param>
/// <param name="er"></param>
private void NotifyException(TemplateInfo templateInfo, Exception er)
{
_currentIndex++;
OnNotifyChanged( new NotifyChangedEventArgs(NotifyType.Error,
string.Format( " 代碼 {0} 生成失敗。{1} ", templateInfo.Title, er.Message),
_currentIndex, _totalCount));
}
public override IEnumerable<TemplateInfo> GetTemplateInfos()
{
return StaticResources.GetTemplateInfos();
}
}
}
所生成的代碼的主要特征如下:
1、主界面是一個基本Google在線地圖的GIS應用,對GIS感興趣的朋友可以進一步深入了解。
添加GIS圖層的代碼如下:

/// 添加GIS圖層
/// </summary>
private void AddPictureMarkerAndTextGraphics()
{
GraphicsLayer graphicsLayer = MyMap.Layers[ " MyGraphicsLayer "] as GraphicsLayer;
var graphics=graphicsLayer.Graphics;
if(graphics== null || graphics.Count== 0) return;
var graphic = graphics[ 0];
if (!graphic.Attributes.ContainsKey( " Description "))
graphic.Attributes.Add( " Description ",
" 專注於代碼生成器、組件、控件、中間件的開發 ");
if (!graphic.Attributes.ContainsKey( " QQ "))
graphic.Attributes.Add( " QQ ", " 1335255648 19892257 ");
}
GIS界面效果圖如下(可是有動畫效果的,試過才知道哈):

2、合理的布局、超炫的界面主題、方便易用的界面,簡直就是OutLook樣式和Rabbion樣式的完美結合,點擊OutLook導航中的列表項可自動加載其對應的Rabbion控件菜單。
3、可切換界面主題,可分別設置並為每個登錄用戶下每個功能模塊單獨自動保存相應的界面設置和布局(如個性化的分組、顯示或隱藏分割線、顯示或隱藏行瞄點等等),超級強悍:
4、真正模塊化的設計,一鍵生成源代碼並可直接在VS中運行。插件所生成的完整源代碼使你可隨心所欲地對代碼進行根據個性化的修改。
5、多層架構,MVVM層使用Catel,界面層使用DevExpress。
解決方案的項目組織結構圖:
基於Catel的Command模式Demo代碼如下:

public ModuleObjectDetail(EditableObject editObject, object tag)
: this(editObject) {
Tag = tag;
}
public ModuleObjectDetail(EditableObject editObject) {
EditObject = editObject;
CommandSave = new Command< object>(OnCommandSaveExecute, OnCommandSaveCanExecute);
CommandSaveAndDispose = new Command< object>(OnCommandSaveAndDisposeExecute, OnCommandSaveAndDisposeCanExecute);
CommandClose = new Command< object>(OnCommandCloseExecute, OnCommandCloseCanExecute);
}
6、自動集成完整的用戶管理、角色管理、權限可控制到每個細粒度的操作,如果數據庫類型為SQL Server,則還將為您自動安裝和權限管理有關的表結構。讓你更加專注於業務邏輯層的開發:
7、已集成基本的字段驗證功能。

界面集成的代碼超級簡單,只需在對應的XAML文件中對要驗證的實體屬性指定如下語句即可,字段級的驗證可是通用的哦(基本的驗證代碼在代碼生成的時候已為您自動集成),Demo代碼如下:

< helpers:ValidationInfo EditName0 ="IDEdit" Rule =" {StaticResource ValidationRuleForField} " />
< helpers:BindingInfo ElementName ="CodeEdit" Property =" {x:Static dxe:BaseEdit.EditValueProperty} " Value =" {Binding EditObject.YbObject.Code, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} " />
< helpers:ValidationInfo EditName1 ="CodeEdit" Rule =" {StaticResource ValidationRuleForField} " />
< helpers:BindingInfo ElementName ="NameEdit" Property =" {x:Static dxe:BaseEdit.EditValueProperty} " Value =" {Binding EditObject.YbObject.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} " />
< helpers:ValidationInfo EditName2 ="NameEdit" Rule =" {StaticResource ValidationRuleForField} " />
< helpers:BindingInfo ElementName ="BeginTimeEdit" Property =" {x:Static dxe:BaseEdit.EditValueProperty} " Value =" {Binding EditObject.YbObject.BeginTime, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} " />
< helpers:ValidationInfo EditName3 ="BeginTimeEdit" Rule =" {StaticResource ValidationRuleForField} " />
< helpers:BindingInfo ElementName ="TimeLimitEdit" Property =" {x:Static dxe:BaseEdit.EditValueProperty} " Value =" {Binding EditObject.YbObject.TimeLimit, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} " />
< helpers:ValidationInfo EditName4 ="TimeLimitEdit" Rule =" {StaticResource ValidationRuleForField} " />
< helpers:BindingInfo ElementName ="CategoryEdit" Property =" {x:Static dxe:BaseEdit.EditValueProperty} " Value =" {Binding EditObject.YbObject.Category, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} " />
< helpers:ValidationInfo EditName5 ="CategoryEdit" Rule =" {StaticResource ValidationRuleForField} " />
< helpers:BindingInfo ElementName ="UnitPriceEdit" Property =" {x:Static dxe:BaseEdit.EditValueProperty} " Value =" {Binding EditObject.YbObject.UnitPrice, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} " />
< helpers:ValidationInfo EditName6 ="UnitPriceEdit" Rule =" {StaticResource ValidationRuleForField} " />
< helpers:BindingInfo ElementName ="RemarkEdit" Property =" {x:Static dxe:BaseEdit.EditValueProperty} " Value =" {Binding EditObject.YbObject.Remark, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} " />
< helpers:ValidationInfo EditName7 ="RemarkEdit" Rule =" {StaticResource ValidationRuleForField} " />
< helpers:BindingInfo ElementName ="CreatedEdit" Property =" {x:Static dxe:BaseEdit.EditValueProperty} " Value =" {Binding EditObject.YbObject.Created, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} " />
< helpers:ValidationInfo EditName8 ="CreatedEdit" Rule =" {StaticResource ValidationRuleForField} " />
< helpers:BindingInfo ElementName ="LastModifiedEdit" Property =" {x:Static dxe:BaseEdit.EditValueProperty} " Value =" {Binding EditObject.YbObject.LastModified, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} " />
< helpers:ValidationInfo EditName9 ="LastModifiedEdit" Rule =" {StaticResource ValidationRuleForField} " />
清爽、干凈的界面層頁面后置代碼:
namespace YbRapidSolution.Wpf {
public partial class ProductEditView : UserControl {
public ProductEditView()
{
InitializeComponent();
}
}
}
8、其他個性化的功能簡直就太多了,而這,僅需你輕輕一點......
附:YbSoftwareFactory 插件開發 SDK 文檔 下載
比較遺憾的是沒有 DexExpress 11.2.8 的漢化文件,自己漢化的話太麻煩,不知誰能提供一個!