ioc初步理解(一) 簡單實用aotufac搭建mvc三層+ioc(codeFirst)
阿新 • • 發佈:2018-12-21
1】首先搭好框架
1.1】搭建ui層
1.2】建立其他內庫檔案
整個專案基本部分搭建完畢之後如下
2】使用nuget引用檔案
先在每一個專案中引入ef
然後再UI層引入以下兩個檔案autofac和Autofac.Mvc5
3】因為本demo實用codefirst,所以先去model層完善
3.1】建立幾個model
建立一個 User.cs。裡面放幾個屬性 id、name、pwd。
3.2】建立DBContext.cs這個檔案的作用是自動生成資料庫 內容如下
3.3】建立DbModelContextFactory.cs。此處作用是:獲取當前EF上下文的唯一例項; 內容如下
4】建立DAL層內容【需要使用nuget引入ef檔案 和model檔案。dal層還需要引入idal】
4.1】首先完善IDAL(介面)內容
4.1.1】首先完成基礎部分,建立IBaseDAL.cs 在裡面新增增刪改查這四個基本操作(注意IDAL中全是介面不是類,所以新建的時候注意吧class改成interface)程式碼如下
public interface IBaseDAL<TEntity> where TEntity : class { #region 1.0 增 void Add(TEntity model);View Code#endregion #region 2.0 刪 void Delete(TEntity model, bool isAddedDbContext); #endregion #region 3.0 改 void Edit(TEntity model, string[] propertyNames); #endregion #region 4.0 查 #region 4.0.1 根據條件查詢 List<TEntity> QueryWhere(Expression<Func<TEntity, bool>> where); #endregion #endregion #region 5.0 統一儲存 /// <summary> /// 統一將EF容器物件中的所有代理類生成相應的sql語句發給db伺服器執行 /// </summary> /// <returns></returns> int SaveChanges(); #endregion }
4.1.2】根據自己在model中建立的模型,在此處也一一對應的建立其dal層介面。所在這裡建立一個IUser_DAL.cs 內容如下:
因為所建立的model只有一個user,所以IDAL層到此結束。
4.2】接下來建立DAL部分內容
4.2.1】首先建立DbContextFactory.cs => //獲取當前EF上下文的唯一例項 程式碼如下
public class DbContextFactory { //獲取當前EF上下文的唯一例項 public static DbContext GetCurrentThreadInstance() { DbContext obj = CallContext.GetData(typeof(DbContextFactory).FullName) as DbContext; if (obj == null) { obj = new DBContext(); CallContext.SetData(typeof(DbContextFactory).FullName, obj); } return obj; } }View Code
4.2.2】首先建立BaseDAL.cs 在裡面寫入具體的增刪該查操作,程式碼如下:
public class BaseDAL<TEntity> : IBaseDAL<TEntity> where TEntity : class {//1.0 例項化EF上下文 DbContext db = DbContextFactory.GetCurrentThreadInstance(); //2.0 定義DbSet<T> 物件 public DbSet<TEntity> _dbset; //3.0 在建構函式的初始化_dbset public BaseDAL() { _dbset = db.Set<TEntity>(); } #region 1.0 增 public virtual void Add(TEntity model) { //1.0 引數合法性驗證 if (model == null) { throw new Exception("BaseRepository泛型類中,新增操作的實體不能為空"); } //2.0 進行新增操作 _dbset.Add(model); } #endregion #region 2.0 刪 public virtual void Delete(TEntity model, bool isAddedDbContext) { //1.0 引數合法性驗證 if (model == null) { throw new Exception("BaseRepository泛型類中,刪除操作的實體不能為空"); } //2.0 進行刪除邏輯處理 if (!isAddedDbContext) { _dbset.Attach(model); } _dbset.Remove(model); } #endregion #region 3.0 改 /// <summary> /// 編輯,約定model 是一個自定義的實體,沒有追加到EF容器中的 /// </summary> /// <param name="model"></param> public virtual void Edit(TEntity model, string[] propertyNames) { //0.0 關閉EF的實體屬性合法性檢查 db.Configuration.ValidateOnSaveEnabled = false; //1.0 引數合法性驗證 if (model == null) { throw new Exception("BaseRepository泛型類中,編輯操作的實體不能為空"); } if (propertyNames == null || propertyNames.Length == 0) { throw new Exception("BaseRepository泛型類中,編輯操作的屬性陣列必須至少有一個值"); } //2.0 將model追加到EF容器中的 DbEntityEntry entry = db.Entry(model); entry.State = EntityState.Unchanged; foreach (var item in propertyNames) { entry.Property(item).IsModified = true; } } #endregion #region 4.0 查 /// <summary> /// 帶條件查詢 /// </summary> /// <param name="where"></param> /// <returns></returns> public virtual List<TEntity> QueryWhere(Expression<Func<TEntity, bool>> where) { return _dbset.Where(where).ToList(); } #endregion #region 5.0 統一儲存 /// <summary> /// 統一將EF容器物件中的所有代理類生成相應的sql語句發給db伺服器執行 /// </summary> /// <returns></returns> public virtual int SaveChanges() { try { return db.SaveChanges(); } catch (Exception ex) { throw ex; } } #endregion }View Code
4.2.3】建立 User_DAL.cs檔案,內容如下
5】建立BLL的內容【需要使用nuget引入ef檔案 和匯入model層。dal層檔案,bll層還需要引入ibll層】
5.1】先建立IBLL(介面)層的內容
5.1.1】建立IBaseBLL.cs。程式碼如下
public interface IBaseBLL<TEntity> where TEntity : class { #region 1.0 增 void Add(TEntity model); #endregion #region 2.0 刪 void Delete(TEntity model, bool isAddedDbContext); #endregion #region 3.0 改 /// <summary> /// 編輯,約定model 是一個自定義的實體,沒有追加到EF容器中的 /// </summary> /// <param name="model"></param> void Edit(TEntity model, string[] propertyNames); #endregion #region 4.0 查 /// <summary> /// 帶條件查詢 /// </summary> /// <param name="where"></param> /// <returns></returns> List<TEntity> QueryWhere(Expression<Func<TEntity, bool>> where); #endregion #region 5.0 統一儲存 /// <summary> /// 統一將EF容器物件中的所有代理類生成相應的sql語句發給db伺服器執行 /// </summary> /// <returns></returns> int SaveChanges(); #endregion }View Code
5.1.2】根據model層的模型建立ibll層介面。所在這裡建立一個IUser_BLL.cs 內容如下:
5.2】完善BLL層內容
5.2.1】建立BaseBLL.cs,程式碼如下
public class BaseBLL<TEntity> : IBaseBLL<TEntity> where TEntity : class { protected IBaseDAL<TEntity> dal = null; #region 1.0 增 public virtual void Add(TEntity model) { dal.Add(model); } #endregion #region 2.0 刪 public virtual void Delete(TEntity model, bool isAddedDbContext) { dal.Delete(model, isAddedDbContext); } #endregion #region 3.0 改 /// <summary> /// 編輯,約定model 是一個自定義的實體,沒有追加到EF容器中的 /// </summary> /// <param name="model"></param> public virtual void Edit(TEntity model, string[] propertyNames) { dal.Edit(model, propertyNames); } #endregion #region 4.0 查 /// <summary> /// 帶條件查詢 /// </summary> /// <param name="where"></param> /// <returns></returns> public virtual List<TEntity> QueryWhere(Expression<Func<TEntity, bool>> where) { return dal.QueryWhere(where); } #endregion #region 5.0 統一儲存 /// <summary> /// 統一將EF容器物件中的所有代理類生成相應的sql語句發給db伺服器執行 /// </summary> /// <returns></returns> public virtual int SaveChanges() { return dal.SaveChanges(); } #endregion }View Code
5.2.2】根據model層的模型建立bll層檔案。所在這裡建立一個User_BLL.cs 程式碼如下:
public class User_BLL : BaseBLL<User>, IUser_BLL { IUser_DAL dalSer; public User_BLL(IUser_DAL dalSer) { base.dal = dalSer; this.dalSer = dalSer; } }View Code
至此,基礎部分建立完畢,接下來建立ui層內容
6】建立UI層內容【需要引入bll檔案和dal檔案 也就是6.1中圖中的兩個檔案,否則autofac報錯,找到不到檔案】
6.1】首先在App_Start資料夾下建AutoFacConfig.cs檔案
程式碼:
public class AutoFacConfig { /// <summary> /// 負責呼叫autofac框架實現業務邏輯層和資料倉儲層程式集中的型別物件的建立 /// 負責建立MVC控制器類的物件(呼叫控制器中的有參建構函式),接管DefaultControllerFactory的工作 /// </summary> public static void Register() { //例項化一個autofac的建立容器 var builder = new ContainerBuilder(); //告訴Autofac框架,將來要建立的控制器類存放在哪個程式集 (IOCtsX.UI) Assembly controllerAss = Assembly.Load("IOCtsX.UI"); builder.RegisterControllers(controllerAss); //告訴autofac框架註冊資料倉儲層所在程式集中的所有類的物件例項 Assembly respAss = Assembly.Load("IOCtsX.IDAL"); //建立respAss中的所有類的instance以此類的實現介面儲存 builder.RegisterTypes(respAss.GetTypes()).AsImplementedInterfaces(); //告訴autofac框架註冊業務邏輯層所在程式集中的所有類的物件例項 Assembly serpAss = Assembly.Load("IOCtsX.BLL"); //建立serAss中的所有類的instance以此類的實現介面儲存 builder.RegisterTypes(serpAss.GetTypes()).AsImplementedInterfaces(); //建立一個Autofac的容器 var container = builder.Build(); //將MVC的控制器物件例項 交由autofac來建立 DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); } }View Code
6.2】然後再Global.asax中進行配置 如下:
6.3】建立一個公共層,使用nuget引入mvc和ef。新增檔案IOCDI.cs 根據建立mode層中模型的數量寫入內容:(寫公共層主要考慮專案的擴充套件性,如果本專案中需要些api或者其他ui層時候,避免程式碼重複)【需要用nuget引入mvc、ef 和ibll層(注意此處mvc版本必須和ui層中mvc版本相同)】
7】最後建立一個控制器新增資料看看,
7.1】先配置Web.config
7.2】建立一個測試控制器(由於是codefirs所以不需要先建立資料庫)
最後檢視資料庫
【最後附上關於autofac的幾點疑惑】
1因為在ui層的App_Start下的AutoFacConfig.cs需要,所以ui層必須引用bll層和dal層,這和三層的理念有些差異。因為三層中ui層並不需要引入dal層。