YbSoftwareFactory 代碼生成插件【六】:WinForm 完美解決方案的代碼生成插件


    “YbRapidSolution for WinForm”是 YbSoftwareFactory 截至目前發布的功能最強大的代碼生成插件,此插件開發的難度超乎想象,應用程序的開發前后斷斷續續接近三個月,把應用程序源代碼轉換為 YbSoftwareFactory 的代碼生成模板用了2周時間,編寫插件源代碼則只用了半天,到最后使用 YbSoftwareFactory 重新生成Demo應用程序並在 Visual Studio 中成功運行,更是前后只用了不到 10 分鍾。對於今后實現同樣效果的應用程序來說,10分鍾 >=  3個月,這就是 YbSoftwareFactory 的價值!

      本插件生成的界面效果和WPF版本的“YbRapidSolution for WPF”插件類似,但底層架構完全不同,全新的設計賦予了其超凡的功能和特性。最重要的是,生成的代碼可是開源的,你可以在 Visual Studio 中不受限制地修改、學習、研究和應用。

    為了讓廣大園友更好地了解 YbSoftwareFactory 的插件編寫原理和過程,現把此插件的全部實現代碼公開,從中你可看出一個插件的開發是如此的簡單:

所有代碼如下
using System;
using System.Collections.Generic;
using System.Linq;
using Yb.CustomTemplating;
using Yb.DbSchemaReader.DataSchema;
using Yb.Plugin.Base;
using Yb.Utility;

namespace Yb.Plugin.EfCslaDx.WinForm
{
     public  abstract  class EfCslaDxWinPluginRepositoryBase : 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,templateInfo.Encoding);
                 // 判斷模板類型,是否每張表都需生成一個模板
                 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)
                        ||templateInfo.ExportFileNameFormatString.Equals( " Web.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}。\r\n{2} ", templateInfo.Title,templateInfo.TemplateRelativePath, er.Message),
                                                       _currentIndex, _totalCount));
        }

         public  override IEnumerable<TemplateInfo> GetTemplateInfos()
        {
             return StaticResources.GetTemplateInfos();
        }
    }
}
EfCslaDxWinEntitiesPluginRepository
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using Yb.CustomTemplating;
using Yb.Plugin.Base;
using Yb.Utility;

namespace Yb.Plugin.EfCslaDx.WinForm
{
    [PluginMetadataAttribute(Name =  " 實體代碼生成 "
        Description =  " 生成 Entity Framework Code First 實體對象 ",
        DisplayOrder =  5,
        ImageUri =  " pack://application:,,,/Yb.Plugin.EfCslaDx.WinForm;component/Images/Win_EF_Entity_64x64.png ",
        LargeImageUri =  " pack://application:,,,/Yb.Plugin.EfCslaDx.WinForm;component/Images/Win_EF_Entity_64x64.png ",
        CodeOutputMode = CodeOutputMode.PreView)]
    [Export(StaticResources.PluginGroupKey, typeof(IPluginRepository))]
     public  class EfCslaDxWinEntitiesPluginRepository : EfCslaDxWinPluginRepositoryBase
    {
         public  override IEnumerable<TemplateInfo> GetTemplateInfos()
        {
             var templateInfo =  base.GetTemplateInfos();
             // 通過 Tag 來計算是否需要使用該模板
             return templateInfo.Where(c => c.BuildEnable && (c.Tag & StaticResources.EntitiesPluginTemplateTag) >  0);
        }
    }
}
EfCslaDxWinBusinessPluginRepository
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using Yb.Plugin.Base;
using Yb.Plugin.EfCslaDx.WinForm;

namespace Yb.Plugin.EfCslaDx.WinForm
{
    [PluginMetadataAttribute(Name =  " CSLA業務邏輯層代碼 ",
        Description =  " 生成基本 CSLA.NET 的業務邏輯層代碼 ",
        DisplayOrder =  15,
        ImageUri =  " pack://application:,,,/Yb.Plugin.EfCslaDx.WinForm;component/Images/CSLA.png ",
        LargeImageUri =  " pack://application:,,,/Yb.Plugin.EfCslaDx.WinForm;component/Images/CSLA.png ",
        CodeOutputMode = CodeOutputMode.PreView)]
    [Export(StaticResources.PluginGroupKey,  typeof(IPluginRepository))]
     public  class EfCslaDxWinBusinessPluginRepository : EfCslaDxWinPluginRepositoryBase
    {
         ///   <summary>
        
///  獲取業務層模板
        
///   </summary>
        
///   <returns></returns>
         public  override IEnumerable<TemplateInfo> GetTemplateInfos()
        {
             var templateInfo =  base.GetTemplateInfos();
             return templateInfo.Where(c => c.BuildEnable && (c.Tag & StaticResources.BusinessPluginTemplateTag) >  0);
        }
    }
}
EfCslaDxWinRepositoriesPluginRepository
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using Yb.Plugin.Base;

namespace Yb.Plugin.EfCslaDx.WinForm
{
    [PluginMetadataAttribute(Name =  " 數據訪問層代碼 ",
        Description =  " 生成數據訪問層代碼 ",
        DisplayOrder =  10,
        ImageUri =  " pack://application:,,,/Yb.Plugin.EfCslaDx.WinForm;component/Images/Win_EF_Respository_64x64.png ",
        LargeImageUri =  " pack://application:,,,/Yb.Plugin.EfCslaDx.WinForm;component/Images/Win_EF_Respository_64x64.png ",
        CodeOutputMode = CodeOutputMode.PreView)]
    [Export(StaticResources.PluginGroupKey,  typeof(IPluginRepository))]
     public  class EfCslaDxWinRepositoriesPluginRepository : EfCslaDxWinPluginRepositoryBase
    {
         ///   <summary>
        
///  獲取界面層模板
        
///   </summary>
        
///   <returns></returns>
         public  override IEnumerable<TemplateInfo> GetTemplateInfos()
        { var templateInfo =  base.GetTemplateInfos();
             return templateInfo.Where(c => c.BuildEnable && (c.Tag & StaticResources.RepositoryPluginTemplateTag) >  0);
        }
    }
}
EfCslaDxWinUIPluginRepository
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using Yb.Plugin.Base;
using Yb.Plugin.EfCslaDx.WinForm;

namespace Yb.Plugin.EfCslaDx.WinForm
{
    [PluginMetadataAttribute(Name =  " WinForm界面層代碼 ",
        Description =  " 生成DevExpress界面層代碼 ",
        DisplayOrder =  20,
        ImageUri =  " pack://application:,,,/Yb.Plugin.EfCslaDx.WinForm;component/Images/DXv2.png ",
        LargeImageUri =  " pack://application:,,,/Yb.Plugin.EfCslaDx.WinForm;component/Images/DXv2.png ",
        CodeOutputMode = CodeOutputMode.PreView)]
    [Export(StaticResources.PluginGroupKey,  typeof(IPluginRepository))]
     public  class EfCslaDxWinUIPluginRepository : EfCslaDxWinPluginRepositoryBase
    {
         ///   <summary>
        
///  獲取界面層模板
        
///   </summary>
        
///   <returns></returns>
         public  override IEnumerable<TemplateInfo> GetTemplateInfos()
        {
             var templateInfo =  base.GetTemplateInfos();
             return templateInfo.Where(c => c.BuildEnable && (c.Tag & StaticResources.WinFormPluginTemplateTag) >  0);
        }
    }
}
EfCslaDxWinSolutionPluginRepository
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Yb.Plugin.Base;
using Yb.Utility;

namespace Yb.Plugin.EfCslaDx.WinForm
{
    [PluginMetadataAttribute(Name =  " 解決方案 ",
        Description =  " 生成Castel數據訪問層,Catel視圖模型層,DevExpress界面層代碼的解決方案 ",
        DisplayOrder =  100,
        ImageUri =  " pack://application:,,,/Yb.Plugin.EfCslaDx.WinForm;component/Images/Win.png ",
        LargeImageUri =  " pack://application:,,,/Yb.Plugin.EfCslaDx.WinForm;component/Images/Win.png ",
        CodeOutputMode = CodeOutputMode.File)]
    [Export(StaticResources.PluginGroupKey,  typeof(IPluginRepository))]
     public  class EfCslaDxWinSolutionPluginRepository : EfCslaDxWinPluginRepositoryBase
    {
         private  const  string ZipFileRelativePath =  @" Plugin\Yb.Plugin.EfCslaDx.WinForm\ZipFiles\YbRapidSolution.Win.zip ";

         protected  override  int GetShouldBuildCodeNum( int listCount)
        {
             var templateCount = GetTemplateInfos().Count();
             return listCount * (templateCount - 12)+  12;
        }

         ///   <summary>
        
///  解壓文件到指定路徑
        
///   </summary>
        
///   <param name="path"> 解壓路徑 </param>
         public  override  void BeforeBuild( string path)
        {
            OnNotifyChanged( new NotifyChangedEventArgs(NotifyType.Infomation,  " 正在解壓文件,請稍候 "));
             // 解壓文件到指定路徑
            FileUtility.ExtractFileTo(ZipFileRelativePath, path);
            OnNotifyChanged( new NotifyChangedEventArgs(NotifyType.Infomation,  " 解壓文件結束 "));
        }
         ///   <summary>
        
///  獲取本插件所需的模板信息
        
///   </summary>
        
///   <returns></returns>
         public  override IEnumerable<TemplateInfo> GetTemplateInfos()
        {
             var templateInfo =  base.GetTemplateInfos();
             return templateInfo.Where(c => c.BuildEnable && (c.Tag & StaticResources.SolutionPluginTemplateTag) >  0);
        }
         ///   <summary>
        
///  安裝和權限有關的數據庫腳本
        
///   </summary>
        
///   <param name="dataSourceInfo"></param>
         public  override  void AfterBuild( object dataSourceInfo)
        {
             if (dataSourceInfo ==  nullreturn;
             var sourceInfo = dataSourceInfo  as DataSourceInfo;
             if (sourceInfo ==  nullreturn;

             var connStr = sourceInfo.DataSourceString;
            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)));
            }
        }

         private  void ExecuteSqlServerDbScript( string connStr)
        {
             var smoUtiltiy =  new SmoUtility(connStr);
             var tableInfos = smoUtiltiy.GetTableInfos();
             // 如果沒有表信息或者不包含默認的和權限有關的表,則執行數據庫表初始化腳本
             if (tableInfos ==  null || tableInfos.Select(c => c.Name).Contains(StaticResources.MembershipConfigTableName))
            {
                OnNotifyChanged( new NotifyChangedEventArgs(NotifyType.Infomation,  " 未安裝數據庫腳本,相關表已存在 "));
                 return;
            }

             // 創建相應表的腳本
             string providerInstallScript = FileUtility.ReadFile( @" Plugin\Yb.Plugin.EfCslaDx.WinForm\Templates\ProviderInstallScript.sql ");
            SqlServerDataUtility.ExecuteSqlServerDbScript(connStr, providerInstallScript);
            OnNotifyChanged( new NotifyChangedEventArgs(NotifyType.Infomation,  " 安裝數據庫腳本成功,應用程序默認登錄名:admin,密碼:123456 "));
        }
    }
}
EfCslaDxWinPluginGroupRepository
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Data;
using System.Linq;
using System.Text;
using Yb.Data;
using Yb.Plugin.Base;
using Yb.Utility;

namespace Yb.Plugin.EfCslaDx.WinForm
{
    [PluginGroupAttribute(
        Name =  " Ef Csla Dx for WinForm ",
        Description =  " 生成 EF 數據訪問層,CSLA.NET 業務邏輯層,DxV2 界面層的 WinForm 代碼及解決方案 ",
        DisplayOrder =  5,
        DataSourceType = DataSourceType.Database,
        DataSourceName = DataSourceName.SqlDataSource | DataSourceName.AccessDataSource,
        ImageUri =  " pack://application:,,,/Yb.Plugin.EfCslaDx.WinForm;component/Images/WinFormGroup.png ",
        LargeImageUri =  " pack://application:,,,/Yb.Plugin.EfCslaDx.WinForm;component/Images/WinFormGroup.png ",
        NavigationGroup =  " Ef Csla Dx 代碼生成插件 ")]
    [Export( typeof(IPluginGroupRepository))]
     public  class EfCslaDxWinPluginGroupRepository : IPluginGroupRepository, IPartImportsSatisfiedNotification
    {
        [ImportMany(StaticResources.PluginGroupKey, AllowRecomposition =  true)]
         public IEnumerable<Lazy<IPluginRepository, IPluginMetadata>> LazyPluginRepositories {  getset; }

         public  void OnImportsSatisfied()
        {
            LazyPluginRepositories = LazyPluginRepositories.OrderBy(c => c.Metadata.DisplayOrder);
        }
         ///   <summary>
        
///  創建數據源
        
///   </summary>   <param name="arg"></param>
        
///   <returns></returns>
         public  object CreateDataSource( object arg)
        {
             if (!(arg  is DataSourceInfo))
            {
                 throw  new ArgumentException( " 參數不是有效的 DataSourceInfo 類型 "" arg ");
            }
             var dataSourceInfo = arg  as DataSourceInfo;
             if (dataSourceInfo ==  nullthrow  new ArgumentNullException( " arg "" DataSourceInfo 參數不能為空 ");

             var schemaUtil =  new DbSchemaUtility();
             // 獲取表信息
             try
            {
                 var tableInfos = schemaUtil.GetDbTables(dataSourceInfo);
                 // 過濾掉和權限有關的表
                 if (tableInfos !=  null && tableInfos.Count >  0)
                    tableInfos = tableInfos.Where(c => !StaticResources.SecurityDbTablesName.Contains(c.Name)).ToList();
                 return tableInfos;
            }
             catch (Exception er)
            {
                 throw  new DataException( string.Format( " 獲取表信息失敗,{0} ", er.Message));
            }
        }

         ///   <summary>
        
///  初始化模板
        
///   </summary>
        
///   <returns></returns>
         public IEnumerable<TemplateInfo> GetTemplateInfos()
        {
             return StaticResources.GetTemplateInfos();
        }
    }
}

有圖有真相:

1、生成代碼后使用Visual Studio打開即可直接調試運行,甚至無需配置數據庫連接字符串等等。

    YbSoftwareFactory 中的 “YbRapidSolution for WinForm” 插件

   

    生成的解決方案運行后的主界面效果圖如下:

   

2、數據訪問層使用Entity Framework,一鍵生成  Code First 代碼,大大提高了二次開發的靈活性。

生成的 Code First 代碼
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Reflection;
using YbRapidSolution.Data;

namespace YbRapidSolution.Entities
{
     ///   <summary>
    
///  Object context
    
///   </summary>
     public  class YbObjectContext : YbDbContext
    {
         public YbObjectContext( string nameOrConnectionString)
            :  base(nameOrConnectionString)
        {
             this.Database.CompatibleWithModel( false);
             // Database.SetInitializer(
            
//     new DropCreateDatabaseIfModelChanges<YbObjectContext>());
            Database.SetInitializer( new CreateDatabaseIfNotExists<YbObjectContext>());
        }
         public IDbSet<Categories> Categories {  getset; }
         public IDbSet<Customers> Customers {  getset; }
         public IDbSet<Employees> Employees {  getset; }
         public IDbSet<Orders> Orders {  getset; }
         public IDbSet<Products> Products {  getset; }
         public IDbSet<Shippers> Shippers {  getset; }
         public IDbSet<Suppliers> Suppliers {  getset; }
         protected  override  void OnModelCreating(DbModelBuilder modelBuilder)
        {
             // 使用Attribute進行配置,則取消注釋如下代碼
            
// ContextConfiguration(modelBuilder);
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
             this.Configuration.LazyLoadingEnabled =  true;
             base.OnModelCreating(modelBuilder);
        }
         private  void ContextConfiguration(DbModelBuilder modelBuilder)
        {
             var contextConfiguration =  new ContextConfiguration();
             var catalog =  new AssemblyCatalog(Assembly.GetExecutingAssembly());
             var container =  new CompositionContainer(catalog);
            container.ComposeParts(contextConfiguration);

             foreach ( var configuration  in
                contextConfiguration.Configurations)
            {
                configuration.AddConfiguration(
                    modelBuilder.Configurations);
            }
        }
    }
}

3、支持 N-Tier 層部署,簡單地修改配置文件就可在本地部署和 N-Tier 層部署之間切換,靈活性超強。同時,服務層無需額外編寫復雜的代碼,只需你去配置。如下為服務層的文件結構,夠簡單吧:-)

   

4、支持對象狀態跟蹤,能自動識別對象是否被修改,修改后窗體標題使用“*”標記,並且未保存直接點擊關閉按鈕時將會自動彈出保存確認對話框。

   

5、多達 40 種界面主題,除了炫還是炫。。。

   

6、每個用戶可以單獨設置窗體主題和布局的設置選項。所有窗體的主題、布局都能為每個登錄用戶單獨、自動進行保存,用戶下次登錄后可自動恢復這些主題和布局,超強的用戶體驗讓你過目難忘。

   

7、每個List列表視圖模塊可快速對本模塊的界面進行定制並為每個用戶單獨保存界面布局並在下次登錄后自動加載。

   

8、List列表視圖支持Grid網格布局和Card卡片布局,用戶可以自由切換,下次登錄時將為該模塊自動加載相應的界面布局模式。

    視圖切換:

   

    切換在Card卡片視圖模式下具有動畫效果的旋轉模式,非常的Cool:

   

    Card卡片模式下的水平布局方式:

   

9、Card卡片視圖支持多種模式切換,可以通過工具條進行定制,每個登錄用戶可在運行時單獨對界面布局進行設計並保存,還是讓用戶來設計吧。

   

10、Detail明細視圖同樣支持用戶在運行時對指定模塊的界面布局進行個性化設計,下次該用戶重新登錄后能自動恢復該用戶設計的模塊界面布局。

   

11、類似 VS 的可拖拽、浮動和停靠窗口:

   

12、生成的代碼自動處理關聯,看看下拉框的例子。

   

13、超級強悍的打印預覽與導出功能

    Grid表格模式下的打印預覽效果圖

   

    Card卡片模式下的打印預覽效果圖

   

    導出格式多樣

   

14、生成的代碼自動集成了數據有效性驗證,當前使用的驗證方式是.NET Framework 已集成的“Data Annotations”驗證。

    自動生成的驗證邏輯如下,沒錯就是這么簡單:

Validate
if (editObject ==  null)
                editObject = CreateNewObject();
             var validateRule = ValidationRulesHelper.CslaValidationRule(editObject);
            ValidationProvider.SetValidationRule(editCategoryID, validateRule);
            ValidationProvider.SetValidationRule(editCategoryName, validateRule);
            ValidationProvider.SetValidationRule(editDescription, validateRule);

    數據驗證失敗的界面效果圖如下:

   

15、提供同時支持N-Tier層部署和本地部署的身份驗證、授權和權限管理組件,統一的 API 底層接口讓你可以在Web、WPF、Silverlight和WinForm的任何項目中同時並輕松調用,並且你還可隨意對權限的層次進行設計和擴展,具有極強的靈活性和通用性。

    角色權限管理模塊支持細粒度的操作權限:

   

    用戶角色管理界面:

   

16、生成的代碼集成了支持 N-Tier 層部署和本地部署的可緩存的數據字典管理,讓你更方便、快速、高效地進行后續的個性化開發。同樣,提供的 API 接口讓你可以在任何類型的項目中同時輕松調用。。。

    ConcreteData數據字典界面:
   
    HierarchyData數據字典界面:
   

17、提供非常靈活的依賴注入接口,你可自由設置你熟悉的依賴注入工具,如下配置使用了 Autofac 依賴注入工具。

    注:Autofac是默認的依賴注入工具

Autofac依賴注入
using Autofac;
using AutofacContrib.CommonServiceLocator;
using Microsoft.Practices.ServiceLocation;
using YbRapidSolution.Core.Infrastructure;
using YbRapidSolution.Data;
using YbRapidSolution.Entities;

namespace YbRapidSolution.Win
{
     public  class AutofacBootStrapper : CommonBootStrapper
{
     protected  override IServiceLocator CreateServiceLocator()
    {
         var builder =  new ContainerBuilder();
        RegisterTypes(builder);

         var container = builder.Build();
         return  new AutofacServiceLocator(container);
    }

     private  static  void RegisterTypes(ContainerBuilder builder)
    {
        builder.Register(c=> new YbObjectContext( " YbRapidSolution ")).As<IDbContext>();
        builder.RegisterGeneric( typeof(EfRepository<>)).As( typeof(IRepository<>));
    }

}

18、快速查詢

19、異步加載模式,防止界面假死

   

20、集成Log4net日志,方便你進行程序調試。

   

    近期將在下一章推出“YbRapidSolution for WinForm”插件所生成解決方案的架構介紹,並提供本 Demo 應用程序的下載地址,可親自下載體驗實際運行效果,請繼續關注。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM