IoC~MVC3+EF+Autofac實現松耦合的系統架構


MVC3+EF+Autofac網上這種文章確實沒有,呵呵,今天就寫一個,代大家分享!

 

這個系列的文章將帶我們進入一種新的開發模式,注入開發模式,或者叫它IOC模式,說起IOC你可以這樣去理解它,它為你的某個實現流出一個注入點,你生產的對象,可以根據你之前的配置進行組合,這是可以的。而注入點的位置及方式也是多種多樣的,我們今天主要說一個通過HTTP請求進行注入的方式,IOC工具使用高效的

Autofac,對它的認識你可以看這篇文章

首先看一下我們這個項目的知識點:

MVC3~一個對UI層進行分層的架構模式,在微軟的MVC3中加入了開源的Razor引擎

EF~這無疑是微軟自己比較成功的ORM工具,它執行效率上要高於linq to sql,甚至你自己編寫的ado.net腳本。

Autofac~這是在orchard項目中被廣泛的IoC工具,它支持類型,反泛,HTTP等注入

對於這個系統的autofac部分,我們將它的注入點放在controller的構造函數中,將生產的對象配置在global中,當然,你也可以設置在config文件,或者你自己的XML文件。

我認為它的工作方式應該是:

網站啟動=>從global中得到ioc配置信息=>http request請求頁面=>通過controller中的參數進行實現的創建=>action中使用創建好的對象

OK,有了這樣一個理論基礎,我們來看一下代碼吧:

EF部分的DATA層

  1   /// <summary>
  2     /// EF數據結構實現
  3     /// </summary>
  4     /// <typeparam name="T"></typeparam>
  5     public class Repository<T> : IRepository<T> where T : class
  6     {
  7         private readonly DbContext _db;
  8 
  9         public Repository()
 10         {
 11             Logger = NullLogger.Instance;
 12             _db = new EEE114Entities();
 13         }
 14 
 15         public ILogger Logger { get; set; }
 16         #region IRepository<T> 成員
 17         List<string> _columns;
 18         public Repository<T> AddColumn(Func<string> func)
 19         {
 20             _columns.Add(func());
 21             return this;
 22         }
 23         #region Create,Update,Delete
 24         public virtual void Create(T entity)
 25         {
 26             Logger.Debug("Create {0}", entity);
 27             _db.Entry<T>(entity);
 28             _db.Set<T>().Add(entity);
 29         }
 30 
 31         public virtual void Update(T entity)
 32         {
 33             Logger.Debug("Update {0}", entity);
 34             _db.Set<T>().Attach(entity);
 35             var ObjectStateEntry = ((IObjectContextAdapter)_db).ObjectContext.ObjectStateManager.GetObjectStateEntry(entity);
 36             string[] p = { };
 37             Array.ForEach(p, x =>
 38             {
 39                 ObjectStateEntry.SetModifiedProperty(x.Trim());
 40             });
 41         }
 42 
 43         public virtual void Delete(T entity)
 44         {
 45             Logger.Debug("Delete {0}", entity);
 46             _db.Set<T>().Attach(entity);
 47             _db.Set<T>().Remove(entity);
 48         }
 49 
 50         public virtual void SaveChanges()
 51         {
 52             try
 53             {
 54                 _db.SaveChanges();
 55             }
 56             catch (System.Data.Entity.Infrastructure.DbUpdateException ex)
 57             {
 58                 string Message = "error:";
 59                 if (ex.InnerException == null)
 60                     Message += ex.Message + ",";
 61                 else if (ex.InnerException.InnerException == null)
 62                     Message += ex.InnerException.Message + ",";
 63                 else if (ex.InnerException.InnerException.InnerException == null)
 64                     Message += ex.InnerException.InnerException.Message + ",";
 65                 throw new Exception(Message);
 66             }
 67         }
 68         #endregion
 69 
 70         #region Get
 71         public virtual int Count(Expression<Func<T, bool>> predicate)
 72         {
 73             return Fetch(predicate).Count();
 74         }
 75         public T Get(params object[] id)
 76         {
 77             throw new NotImplementedException();
 78         }
 79         public virtual T Get(Expression<Func<T, bool>> predicate)
 80         {
 81             return Fetch(predicate).SingleOrDefault();
 82         }
 83         public IQueryable<T> Table
 84         {
 85             get { return _db.Set<T>(); }
 86         }
 87 
 88         public IEnumerable<T> Fetch(Expression<Func<T, bool>> predicate)
 89         {
 90             return Table.Where(predicate);
 91         }
 92 
 93         public IEnumerable<T> Fetch(Expression<Func<T, bool>> predicate, Action<Orderable<T>> order)
 94         {
 95             var orderable = new Orderable<T>(Fetch(predicate).AsQueryable());
 96             order(orderable);
 97             return orderable.Queryable;
 98         }
 99 
100         public IEnumerable<T> Fetch(Expression<Func<T, bool>> predicate, Action<Orderable<T>> order, int skip, int count)
101         {
102             return Fetch(predicate, order).Skip(skip).Take(count);
103         }
104         #endregion
105 
106         #endregion
107     }

Services層(BLL層)核心代碼:

 1  /// <summary>
 2     /// 網站異常業務
 3     /// </summary>
 4     public class Web_ExceptionLogManager : IWeb_ExceptionLogManager
 5     {
 6         IRepository<Web_ExceptionLog> _web_ExceptionLogRepository;
 7         public Web_ExceptionLogManager(IRepository<Web_ExceptionLog> web_ExceptionLogRepository)
 8         {
 9             _web_ExceptionLogRepository = web_ExceptionLogRepository;
10         }
11         #region IWeb_ExceptionLogManager 成員
12 
13         public List<Web_ExceptionLog> GetWeb_ExceptionLog()
14         {
15             return _web_ExceptionLogRepository.Fetch(i => i.FullInfo != null, i => i.Asc(j => j.OccurTime)).ToList();
16 
17         }
18 
19         #endregion
20     }

WEB層MVC部分代碼:

 1  public class HomeController : Controller
 2     {
 3         IRepository<Web_Logs> _iRepository;
 4         IWeb_ExceptionLogManager _web_ExceptionLogManager;
 5 
 6         public HomeController(IRepository<Web_Logs> iRepository, IWeb_ExceptionLogManager web_ExceptionLogManager)
 7         {
 8             _iRepository = iRepository;
 9             _web_ExceptionLogManager = web_ExceptionLogManager;
10         }
11 
12         public ActionResult Index(int sort = 1)
13         {
14             ViewBag.Message = "歡迎使用 ASP.NET MVC!";
15 
16             var model = _iRepository.Fetch(i => i.Info != null, i => i.Asc(j => j.OccurTime));
17             if (sort != 1)
18                 model = _iRepository.Fetch(i => i.Info != null, i => i.Desc(j => j.OccurTime));
19 
20             ViewBag.Log = _web_ExceptionLogManager.GetWeb_ExceptionLog();
21             return View(model);
22         }

而注入參數我們放在global中,看一下核心代碼:

 1  protected void Application_Start()
 2         {
 3             #region Autofac注入
 4             var builder = new ContainerBuilder();
 5             builder.RegisterControllers(Assembly.GetExecutingAssembly());
 6             builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerHttpRequest();
 7 
 8             builder.RegisterType<Web_ExceptionLogManager>().As<IWeb_ExceptionLogManager>().InstancePerHttpRequest(); //從HTTP請求中重到注入點
 9 
10             IContainer container = builder.Build();
11             DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
12             #endregion
13 
14             AreaRegistration.RegisterAllAreas();
15             RegisterGlobalFilters(GlobalFilters.Filters);
16             RegisterRoutes(RouteTable.Routes);
17         }

OK,我們運行后,在/Home/Index中自己運行HTTP請求把global中的對象進行創建,當然,它在創建對象時,你可以是DATA層,或者是SERVICE層的,這里

沒有考慮WEB不能與DATA通訊問題,實際項目中,我們的WEB層不應該有對DATA層的引用,所以,WEB層一般只注入SERVICE的對象,這一點是需要注意的。

 


免責聲明!

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



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