本系列目錄:ASP.NET MVC4入門到精通系列目錄匯總
業務層調用數據層對象,我不想每次都new一個數據層對象,而是在數據層創建一個倉儲,統一管理所有的對象調用。
1、在IDAL項目中,新建IDBSession.tt模板

<#@ template language="C#" debug="false" hostspecific="true"#> <#@ include file="EF.Utility.CS.ttinclude"#><#@ output extension=".cs"#> <# CodeGenerationTools code = new CodeGenerationTools(this); MetadataLoader loader = new MetadataLoader(this); CodeRegion region = new CodeRegion(this, 1); MetadataTools ef = new MetadataTools(this); string inputFile = @"..\MODEL\OA.edmx"; EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile); string namespaceName = code.VsNamespaceSuggestion(); EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this); #> using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace IDAL { public partial interface IDBSession { <# // Emit Entity Types foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name)) { #> I<#=entity.Name#>DAL I<#=entity.Name#>DAL{get;set;} <#}#> } }
Ctrl+S后自動生成IDBSession接口

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace IDAL { public partial interface IDBSession { IBill_LeaveDAL IBill_LeaveDAL{get;set;} IoldWF_AutoTransactNodeDAL IoldWF_AutoTransactNodeDAL{get;set;} IoldWF_BillFlowNodeDAL IoldWF_BillFlowNodeDAL{get;set;} IoldWF_BillFlowNodeRemarkDAL IoldWF_BillFlowNodeRemarkDAL{get;set;} IoldWF_BillStateDAL IoldWF_BillStateDAL{get;set;} IoldWF_NodeDAL IoldWF_NodeDAL{get;set;} IoldWF_NodeStateDAL IoldWF_NodeStateDAL{get;set;} IoldWF_WorkFlowDAL IoldWF_WorkFlowDAL{get;set;} IoldWF_WorkFlowNodeDAL IoldWF_WorkFlowNodeDAL{get;set;} IOu_DepartmentDAL IOu_DepartmentDAL{get;set;} IOu_PermissionDAL IOu_PermissionDAL{get;set;} IOu_RoleDAL IOu_RoleDAL{get;set;} IOu_RolePermissionDAL IOu_RolePermissionDAL{get;set;} IOu_UserInfoDAL IOu_UserInfoDAL{get;set;} IOu_UserRoleDAL IOu_UserRoleDAL{get;set;} IOu_UserVipPermissionDAL IOu_UserVipPermissionDAL{get;set;} IW_WorkFlowDAL IW_WorkFlowDAL{get;set;} IW_WorkFlowBranchDAL IW_WorkFlowBranchDAL{get;set;} IW_WorkFlowNodeDAL IW_WorkFlowNodeDAL{get;set;} IW_WrokFlowRoleDAL IW_WrokFlowRoleDAL{get;set;} IWR_WorkFlowApplyDAL IWR_WorkFlowApplyDAL{get;set;} IWR_WrokFlowApplyDetailsDAL IWR_WrokFlowApplyDetailsDAL{get;set;} } }
2、在DAL項目中實現IDBSession接口
新建DBSession.tt模板

<#@ template language="C#" debug="false" hostspecific="true"#> <#@ include file="EF.Utility.CS.ttinclude"#><#@ output extension=".cs"#> <# CodeGenerationTools code = new CodeGenerationTools(this); MetadataLoader loader = new MetadataLoader(this); CodeRegion region = new CodeRegion(this, 1); MetadataTools ef = new MetadataTools(this); string inputFile = @"..\MODEL\OA.edmx"; EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile); string namespaceName = code.VsNamespaceSuggestion(); EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this); #> using System; using System.Collections.Generic; using System.Linq; using System.Text; using IDAL; namespace DAL { public partial class DBSession:IDBSession { <# int index=0; // Emit Entity Types foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name)) { index++; #> #region <#=index #> 數據接口 I<#=entity.Name#>DAL I<#=entity.Name#>DAL i<#=entity.Name#>DAL; public I<#=entity.Name#>DAL I<#=entity.Name#>DAL{ get { if(i<#=entity.Name#>DAL==null) i<#=entity.Name#>DAL=new <#=entity.Name#>DAL(); return i<#=entity.Name#>DAL; } set { i<#=entity.Name#>DAL=value; } } #endregion <#}#> } }
Ctrl+S后自動生成DBSession類

using System; using System.Collections.Generic; using System.Linq; using System.Text; using IDAL; namespace DAL { public partial class DBSession:IDBSession { #region 1 數據接口 IBill_LeaveDAL IBill_LeaveDAL iBill_LeaveDAL; public IBill_LeaveDAL IBill_LeaveDAL{ get { if(iBill_LeaveDAL==null) iBill_LeaveDAL=new Bill_LeaveDAL(); return iBill_LeaveDAL; } set { iBill_LeaveDAL=value; } } #endregion #region 2 數據接口 IoldWF_AutoTransactNodeDAL IoldWF_AutoTransactNodeDAL ioldWF_AutoTransactNodeDAL; public IoldWF_AutoTransactNodeDAL IoldWF_AutoTransactNodeDAL{ get { if(ioldWF_AutoTransactNodeDAL==null) ioldWF_AutoTransactNodeDAL=new oldWF_AutoTransactNodeDAL(); return ioldWF_AutoTransactNodeDAL; } set { ioldWF_AutoTransactNodeDAL=value; } } #endregion #region 3 數據接口 IoldWF_BillFlowNodeDAL IoldWF_BillFlowNodeDAL ioldWF_BillFlowNodeDAL; public IoldWF_BillFlowNodeDAL IoldWF_BillFlowNodeDAL{ get { if(ioldWF_BillFlowNodeDAL==null) ioldWF_BillFlowNodeDAL=new oldWF_BillFlowNodeDAL(); return ioldWF_BillFlowNodeDAL; } set { ioldWF_BillFlowNodeDAL=value; } } #endregion #region 4 數據接口 IoldWF_BillFlowNodeRemarkDAL IoldWF_BillFlowNodeRemarkDAL ioldWF_BillFlowNodeRemarkDAL; public IoldWF_BillFlowNodeRemarkDAL IoldWF_BillFlowNodeRemarkDAL{ get { if(ioldWF_BillFlowNodeRemarkDAL==null) ioldWF_BillFlowNodeRemarkDAL=new oldWF_BillFlowNodeRemarkDAL(); return ioldWF_BillFlowNodeRemarkDAL; } set { ioldWF_BillFlowNodeRemarkDAL=value; } } #endregion #region 5 數據接口 IoldWF_BillStateDAL IoldWF_BillStateDAL ioldWF_BillStateDAL; public IoldWF_BillStateDAL IoldWF_BillStateDAL{ get { if(ioldWF_BillStateDAL==null) ioldWF_BillStateDAL=new oldWF_BillStateDAL(); return ioldWF_BillStateDAL; } set { ioldWF_BillStateDAL=value; } } #endregion #region 6 數據接口 IoldWF_NodeDAL IoldWF_NodeDAL ioldWF_NodeDAL; public IoldWF_NodeDAL IoldWF_NodeDAL{ get { if(ioldWF_NodeDAL==null) ioldWF_NodeDAL=new oldWF_NodeDAL(); return ioldWF_NodeDAL; } set { ioldWF_NodeDAL=value; } } #endregion #region 7 數據接口 IoldWF_NodeStateDAL IoldWF_NodeStateDAL ioldWF_NodeStateDAL; public IoldWF_NodeStateDAL IoldWF_NodeStateDAL{ get { if(ioldWF_NodeStateDAL==null) ioldWF_NodeStateDAL=new oldWF_NodeStateDAL(); return ioldWF_NodeStateDAL; } set { ioldWF_NodeStateDAL=value; } } #endregion #region 8 數據接口 IoldWF_WorkFlowDAL IoldWF_WorkFlowDAL ioldWF_WorkFlowDAL; public IoldWF_WorkFlowDAL IoldWF_WorkFlowDAL{ get { if(ioldWF_WorkFlowDAL==null) ioldWF_WorkFlowDAL=new oldWF_WorkFlowDAL(); return ioldWF_WorkFlowDAL; } set { ioldWF_WorkFlowDAL=value; } } #endregion #region 9 數據接口 IoldWF_WorkFlowNodeDAL IoldWF_WorkFlowNodeDAL ioldWF_WorkFlowNodeDAL; public IoldWF_WorkFlowNodeDAL IoldWF_WorkFlowNodeDAL{ get { if(ioldWF_WorkFlowNodeDAL==null) ioldWF_WorkFlowNodeDAL=new oldWF_WorkFlowNodeDAL(); return ioldWF_WorkFlowNodeDAL; } set { ioldWF_WorkFlowNodeDAL=value; } } #endregion #region 10 數據接口 IOu_DepartmentDAL IOu_DepartmentDAL iOu_DepartmentDAL; public IOu_DepartmentDAL IOu_DepartmentDAL{ get { if(iOu_DepartmentDAL==null) iOu_DepartmentDAL=new Ou_DepartmentDAL(); return iOu_DepartmentDAL; } set { iOu_DepartmentDAL=value; } } #endregion #region 11 數據接口 IOu_PermissionDAL IOu_PermissionDAL iOu_PermissionDAL; public IOu_PermissionDAL IOu_PermissionDAL{ get { if(iOu_PermissionDAL==null) iOu_PermissionDAL=new Ou_PermissionDAL(); return iOu_PermissionDAL; } set { iOu_PermissionDAL=value; } } #endregion #region 12 數據接口 IOu_RoleDAL IOu_RoleDAL iOu_RoleDAL; public IOu_RoleDAL IOu_RoleDAL{ get { if(iOu_RoleDAL==null) iOu_RoleDAL=new Ou_RoleDAL(); return iOu_RoleDAL; } set { iOu_RoleDAL=value; } } #endregion #region 13 數據接口 IOu_RolePermissionDAL IOu_RolePermissionDAL iOu_RolePermissionDAL; public IOu_RolePermissionDAL IOu_RolePermissionDAL{ get { if(iOu_RolePermissionDAL==null) iOu_RolePermissionDAL=new Ou_RolePermissionDAL(); return iOu_RolePermissionDAL; } set { iOu_RolePermissionDAL=value; } } #endregion #region 14 數據接口 IOu_UserInfoDAL IOu_UserInfoDAL iOu_UserInfoDAL; public IOu_UserInfoDAL IOu_UserInfoDAL{ get { if(iOu_UserInfoDAL==null) iOu_UserInfoDAL=new Ou_UserInfoDAL(); return iOu_UserInfoDAL; } set { iOu_UserInfoDAL=value; } } #endregion #region 15 數據接口 IOu_UserRoleDAL IOu_UserRoleDAL iOu_UserRoleDAL; public IOu_UserRoleDAL IOu_UserRoleDAL{ get { if(iOu_UserRoleDAL==null) iOu_UserRoleDAL=new Ou_UserRoleDAL(); return iOu_UserRoleDAL; } set { iOu_UserRoleDAL=value; } } #endregion #region 16 數據接口 IOu_UserVipPermissionDAL IOu_UserVipPermissionDAL iOu_UserVipPermissionDAL; public IOu_UserVipPermissionDAL IOu_UserVipPermissionDAL{ get { if(iOu_UserVipPermissionDAL==null) iOu_UserVipPermissionDAL=new Ou_UserVipPermissionDAL(); return iOu_UserVipPermissionDAL; } set { iOu_UserVipPermissionDAL=value; } } #endregion #region 17 數據接口 IW_WorkFlowDAL IW_WorkFlowDAL iW_WorkFlowDAL; public IW_WorkFlowDAL IW_WorkFlowDAL{ get { if(iW_WorkFlowDAL==null) iW_WorkFlowDAL=new W_WorkFlowDAL(); return iW_WorkFlowDAL; } set { iW_WorkFlowDAL=value; } } #endregion #region 18 數據接口 IW_WorkFlowBranchDAL IW_WorkFlowBranchDAL iW_WorkFlowBranchDAL; public IW_WorkFlowBranchDAL IW_WorkFlowBranchDAL{ get { if(iW_WorkFlowBranchDAL==null) iW_WorkFlowBranchDAL=new W_WorkFlowBranchDAL(); return iW_WorkFlowBranchDAL; } set { iW_WorkFlowBranchDAL=value; } } #endregion #region 19 數據接口 IW_WorkFlowNodeDAL IW_WorkFlowNodeDAL iW_WorkFlowNodeDAL; public IW_WorkFlowNodeDAL IW_WorkFlowNodeDAL{ get { if(iW_WorkFlowNodeDAL==null) iW_WorkFlowNodeDAL=new W_WorkFlowNodeDAL(); return iW_WorkFlowNodeDAL; } set { iW_WorkFlowNodeDAL=value; } } #endregion #region 20 數據接口 IW_WrokFlowRoleDAL IW_WrokFlowRoleDAL iW_WrokFlowRoleDAL; public IW_WrokFlowRoleDAL IW_WrokFlowRoleDAL{ get { if(iW_WrokFlowRoleDAL==null) iW_WrokFlowRoleDAL=new W_WrokFlowRoleDAL(); return iW_WrokFlowRoleDAL; } set { iW_WrokFlowRoleDAL=value; } } #endregion #region 21 數據接口 IWR_WorkFlowApplyDAL IWR_WorkFlowApplyDAL iWR_WorkFlowApplyDAL; public IWR_WorkFlowApplyDAL IWR_WorkFlowApplyDAL{ get { if(iWR_WorkFlowApplyDAL==null) iWR_WorkFlowApplyDAL=new WR_WorkFlowApplyDAL(); return iWR_WorkFlowApplyDAL; } set { iWR_WorkFlowApplyDAL=value; } } #endregion #region 22 數據接口 IWR_WrokFlowApplyDetailsDAL IWR_WrokFlowApplyDetailsDAL iWR_WrokFlowApplyDetailsDAL; public IWR_WrokFlowApplyDetailsDAL IWR_WrokFlowApplyDetailsDAL{ get { if(iWR_WrokFlowApplyDetailsDAL==null) iWR_WrokFlowApplyDetailsDAL=new WR_WrokFlowApplyDetailsDAL(); return iWR_WrokFlowApplyDetailsDAL; } set { iWR_WrokFlowApplyDetailsDAL=value; } } #endregion } }
接下來,我們創建DBSession工廠和上下文工廠,目的是為了提高效率,在線程中共用一個對象。
3、IDAL項目中添加IDBSessionFactory接口
namespace IDAL { /// <summary> /// 數據倉儲工廠 /// </summary> public interface IDBSessionFactory { IDBSession GetDBSession(); } }
DAL項目中添加DBSessionFactory類繼承IDBSessionFactory接口
using System.Runtime.Remoting.Messaging; using IDAL; namespace DAL { public class DBSessionFactory : IDBSessionFactory { /// <summary> /// 此方法的作用: 提高效率,在線程中 共用一個 DBSession 對象! /// </summary> /// <returns></returns> public IDBSession GetDBSession() { //從當前線程中 獲取 DBContext 數據倉儲 對象 IDBSession dbSesion = CallContext.GetData(typeof(DBSessionFactory).Name) as DBSession; if (dbSesion == null) { dbSesion = new DBSession(); CallContext.SetData(typeof(DBSessionFactory).Name, dbSesion); } return dbSesion; } } }
4、同樣,我們再來創建一個上下文工廠,即便以后有多個數據庫上下文,也能夠很好的支持。
IDAL項目中,新建IDBContextFactory.cs接口
using System.Data.Entity; namespace IDAL { /// <summary> /// EF數據上下文 工廠 /// </summary> public interface IDBContextFactory { /// <summary> /// 獲取 EF 上下文對象 /// </summary> /// <returns></returns> DbContext GetDbContext(); }
DAL項目中新建DBContextFactory類繼承IDBContextFactory接口
using System.Data.Entity; using System.Runtime.Remoting.Messaging; using Model; namespace DAL { public class DBContextFactory : IDBContextFactory { #region 創建 EF上下文 對象,在線程中共享 一個 上下文對象 + DbContext GetDbContext() /// <summary> /// 創建 EF上下文 對象,在線程中共享 一個 上下文對象 /// </summary> /// <returns></returns> public DbContext GetDbContext() { ////從當前線程中 獲取 EF上下文對象 var dbContext = CallContext.GetData(typeof(DBContextFactory).Name) as DbContext; if (dbContext == null) { dbContext = new OAEntities(); CallContext.SetData(typeof(DBContextFactory).Name, dbContext); } return dbContext; } #endregion } }
5、Common項目中,添加ConfigurationHelper.cs來操作配置文件
using System; using System.Configuration; namespace Common { public static class ConfigurationHelper { public static string AppSetting(string key) { return ConfigurationManager.AppSettings[key]; } } }
Web.config中添加如下配置節點:
<add key="DBSessionFatory" value="DAL.DBSessionFactory" /> <add key="DBSessionFatoryDLL" value="E:\WorkSpace\Study\Webs\MVC\OAsln\Web\bin\DAL.dll" />
6、修改BaseBLL類的調用方式,添加如下代碼:
/// <summary> /// 2.0 數據倉儲接口(相當於數據層工廠,可以創建所有的數據子類對象) /// </summary> private IDAL.IDBSession iDbSession; #region 數據倉儲 屬性 + IDBSession DBSession /// <summary> /// 數據倉儲 屬性 /// </summary> public IDAL.IDBSession DBSession { get { if (iDbSession == null) { //1.讀取配置文件 string strFactoryDLL = Common.ConfigurationHelper.AppSetting("DBSessionFatoryDLL"); string strFactoryType = Common.ConfigurationHelper.AppSetting("DBSessionFatory"); //2.1通過反射創建 DBSessionFactory 工廠對象 Assembly dalDLL = Assembly.LoadFrom(strFactoryDLL); Type typeDBSessionFatory = dalDLL.GetType(strFactoryType); IDAL.IDBSessionFactory sessionFactory = Activator.CreateInstance(typeDBSessionFatory) as IDAL.IDBSessionFactory; //2.2根據配置文件內容 使用 DI層里的Spring.Net 創建 DBSessionFactory 工廠對象 //3.通過 工廠 創建 DBSession對象 iDbSession = sessionFactory.GetDBSession(); } return iDbSession; } } #endregion
在這里,使用到了工廠來創建對象,后面引入了Spring.net之后,會回過頭來優化現有的代碼。項目中使用到了許多接口,目的是為了解耦,每一個項目的職責盡量讓其單一,業務層只讓其調用數據層接口,也是為了依賴於抽象,而不是具體。每一個框架其實都是各種設計模式的一個集合,設計模式是為了解決一類問題,而框架就是為了解決一系列問題了。到現在為止,整個項目的雛形已經出來了,但是后續,我們一步一步來優化,好的框架不是一下子就能設計得完美的,而是能夠不斷的擁抱修改,可持續擴展,不斷改進出來的。