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的对象,这一点是需要注意的。

http://www.cnblogs.com/lori/archive/2012/09/06/2672856.html

你可能感兴趣的:(系统架构)