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); #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; } }
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 }
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 }
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 }
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; } }
至此,基礎部分建立完畢,接下來建立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.DAL"); //創建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)); } }
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層。
【結尾說明,關於了解autofac花掉的時間說長也長說短也短。原本以為在博客園、csdn上面找一找就能馬上得到一個可以運行的demo,但是很多博主都是按照自己的理解去寫,在博文中或多或少會掉一些內容,這些內容對於博主和一些大牛來說是可以忽略不計的,因此博文只需要核心代碼就可以,但是對於我這種萌新來說簡直是災難級別的,因為跟着博主敲打代碼過程中時長因為缺點什么而無法運行,自己也不知道錯誤在哪。因此不得不敲到一半立馬換下一個。導致效率低下。所以在寫這個博文的過程中。我盡量將每一個細節全部羅列出來,以免像我這樣的小白看不懂。照着這個流程講代碼敲出來並且運行時沒什么大問題的。因為我每敲完一處就寫一點。最后將代碼運行完畢,才敢上傳。如果各位看官覺得有什么問題可以在下方留言】
【如果需要代碼可以去此下載,當然懶人也需要一點付出(csdn 3積分)。博主希望大家盡量多動手,多理解。不要像我之前一樣只需要demo從不看文章導致后來吃了許多虧】