对IOC模式与容器Autofac在MVC里面的一些用法

IOC模式与Autofac的实例

一:对于IOC模式(控制翻转)的简单认识可以去参考秋风的博客,他介绍的容器是Unity,http://www.cnblogs.com/qqlin/archive/2012/10/09/2707075.html

二:下面我介绍一下在项目中对IOC模式与Autofac在MVC中的运用

1:用于我们公司数据库用的是pg,所以相应也使用了NHibernate,如果大家使用的数据库是SQL Server,相当于EF

首先定义数据访问的接口:

 1 public interface IRepository<TEntity> where TEntity : EntityBase
 2     {
 3         object Save(TEntity entity);
 4
 5         void SaveOrUpdate(TEntity entity);
 6
 7         IQueryable<TEntity> Query(Expression<Func<TEntity, bool>> predicate = null);
 8
 9         /*
10         /// <summary>
11         /// default id int, sorted in asc
12         /// </summary>
13         PagedList<TEntity> Query(Expression<Func<TEntity, bool>> predicate, int pageIndex, int pageSize);
14
15         PagedList<TEntity> QueryDescending(Expression<Func<TEntity, bool>> predicate, int pageIndex, int pageSize);
16          * */
17
18         /* best practice TId */
19         TEntity Get(object id);
20
21         TEntity Load(object id);
22
23         void Update(TEntity entity);
24         void Update(Action<TEntity> action, Expression<Func<TEntity, bool>> predicate = null);
25
26         void Delete(TEntity entity);
27         void Delete(Expression<Func<TEntity, bool>> predicate = null);
28
29         IEnumerable<TResult> SqlQuery<TResult>(string sql);
30
31         int ExecuteSql(string sql);
32     }

2:我们实现这些接口,里面的Session相当于EF里面的上下文

 public class Repository<TEntity> : IRepository<TEntity> where TEntity : EntityBase
    {
        /*
         * 如何自动将操作打包到一个事物中,如Insert update等
         * linq to sql 中有个SubmitChange方法,一次提交之前修改
         * (Injectiont)
         *
         * 单条sql(一个方法内)的操作很好打包
         *
         * 不同的Repository使用一个session(One Session per Request),如何保证在一个事物中一同提交,单独的repository可以保证所有操作在一个事务中
         * End Request 提交事务的时候异常 这个怎么处理呢?
         *
         * 应该单独出一个UnitOfWork,独立于各repository,然后所有的事务操作在其中完成
         * */

        protected ISession Session
        {
            get { return sessionProvider.Session; }
        }

        private readonly ISessionProvider sessionProvider;

        public Repository(ISessionProvider sessionProvider)
        {
            this.sessionProvider = sessionProvider;
        }

        public object Save(TEntity entity)
        {
            return Session.Save(entity);
        }

        public void SaveOrUpdate(TEntity entity)
        {
            Session.SaveOrUpdate(entity);
        }

        /*
        public TEntity Get(Expression<Func<TEntity, bool>> predicate)
        {
            // SingleOrDefault is translated to ‘limit 1‘ by NHibernate
            return Query()
                .Where(predicate)
                .SingleOrDefault();
        }
        * */

        public IQueryable<TEntity> Query(Expression<Func<TEntity, bool>> predicate = null)
        {
            return predicate == null
                ? Session.Query<TEntity>()
                : Session.Query<TEntity>().Where(predicate);
        }

        /*
        public PagedList<TEntity> Query(Expression<Func<TEntity, bool>> predicate, int pageIndex, int pageSize)
        {
            return Query()
                .Where(predicate)
                .OrderBy(entity => entity.Id)
                .ToPagedList(pageIndex, pageSize);
        }

        public PagedList<TEntity> QueryDescending(Expression<Func<TEntity, bool>> predicate, int pageIndex, int pageSize)
        {
            return Query()
                .Where(predicate)
                .OrderByDescending(entity => entity.Id)
                .ToPagedList(pageIndex, pageSize);
        }
        * */

        public TEntity Get(object id)
        {
            return Session.Get<TEntity>(id);
        }

        public TEntity Load(object id)
        {
            return Session.Load<TEntity>(id);
        }

        public void Update(TEntity entity)
        {
            Session.Update(entity);
        }

        public void Update(Action<TEntity> action, Expression<Func<TEntity, bool>> predicate = null)
        {
            var entities = Query(predicate);

            foreach (var entity in entities)
            {
                action(entity);
                Update(entity);
            }
        }

        public void Delete(TEntity entity)
        {
            Session.Delete(entity);
        }

        public void Delete(Expression<Func<TEntity, bool>> predicate = null)
        {
            var entities = Query(predicate);
            entities.ForEach(Delete);
        }

        public IEnumerable<TResult> SqlQuery<TResult>(string sql)
        {
            return Session
                .CreateSQLQuery(sql)
                .SetScalars(typeof (TResult))
                .SetResultTransformer(Transformers.AliasToBean(typeof (TResult)))
                .Future<TResult>();
        }

        public int ExecuteSql(string sql)
        {
            return Session
                .CreateSQLQuery(sql)
                .ExecuteUpdate();
        }

3:现在要真正完成依赖注入就得AtuoFac登场

(1):用builder.RegisterGeneric(typeof (Repository<>)).As(typeof (IRepository<>)).InstancePerRequest()注册或者也可以builder.RegisterType<Object>().As<Iobject>()注册,我使用的是第一种,当然也可以用通过配置的方式使用AutoFac,也不做介绍了

using Autofac;
using WebPrint.Data.Repositories;

namespace WebPrint.Web.Mvc.IoC
{
    public class RepositoriesModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterGeneric(typeof (Repository<>))
                   .As(typeof (IRepository<>))
                   .InstancePerRequest();
        }
    }
}

 (2)注册你的控制器类,必须的引如Autofac.Integration.Mvc.dll,写在一个公共IOC类中

using System.Web.Http;
using System.Web.Mvc;
using Autofac;
using Autofac.Integration.Mvc;
using Autofac.Integration.WebApi;

namespace WebPrint.Web.Mvc.IoC
{
    public static class IocConfig
    {
        public static void Register(/*params Assembly[] contorllerAssemblies*/)
        {
            var builder = new ContainerBuilder();

            builder.RegisterModule(new RepositoriesModule());

            // register controller
            builder.RegisterControllers(typeof (MvcApplication).Assembly);

            // register api controller
            builder.RegisterApiControllers(typeof (MvcApplication).Assembly);

            // register filters
            // global filters is not working
            builder.RegisterFilterProvider();

            var container = builder.Build();
            // Configure contollers with the dependency resolver
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

            // Configure Web API with the dependency resolver
            GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
        }
    }
}

 (3):到MVCApplication_Start()里面进行注册调用

 protected void Application_Start()
        {
            // Autofac IoC Register
            IocConfig.Register();

            // log4net
            LogConfig.Register();

            //WebApiConfig.Register(GlobalConfiguration.Configuration);
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            //路由注册
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            // 去掉Header中mvc版本的描述
            MvcHandler.DisableMvcResponseHeader = true;
            var config = GlobalConfiguration.Configuration;

            config.Formatters.Remove(config.Formatters.XmlFormatter);
            var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
            jsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            jsonFormatter.SerializerSettings.ContractResolver = new NHibernateContractResolver();
            jsonFormatter.SerializerSettings.Converters.Add(new StringEnumConverter());

#if DEBUG
            // Start profile
            NHibernateProfiler.StartProfiler();
#endif
        }

  (4):到控制器的构造函数中注入依赖代码

namespace WebPrint.Web.Mvc.Areas.Order.Controllers
{
    [RouteArea("order")]
    [RoutePrefix("catalog")]/*MVC5以上的路由机制*/
    [UserAuthorize(Roles = "OrderCatalog")] /* 权限控制 */
    public class CatalogOrderController : Controller
    {
        private IService<Model.Order> orderService;
        private IService<ImportOrder> importOrderService;

        public CatalogOrderController(IService<Model.Order> orderService, IService<ImportOrder> importOrderService)
        {
            this.orderService = orderService;
            this.importOrderService = importOrderService;
        }
        [Route("{page:int?}")]
        public ActionResult List(string strokeNo, string contractNo,int page = 1)
        {

            ViewBag.StrokeNo = strokeNo;
            ViewBag.ContractNo = contractNo;  

            Expression<Func<ImportOrder, bool>> expr = i => i.Active == 0;

            if (!strokeNo.IsNullOrEmpty())
            {
                expr = expr.And(i => i.StrokeNo.ToUpper().Contains(strokeNo.ToUpper().Trim()));
            }

            if (!contractNo.IsNullOrEmpty())
            {
                expr = expr.And(i => i.ContractNo.ToUpper().Contains(contractNo.ToUpper().Trim()));
            }

            //增加按supply no过滤(vendorCode即supply no)
            var user = userService.Load(UserGroupPermission.CookieUser.Id);
            var isAdmin = user.Groups.Any(o => o.Name == Core.Group.RpacAdmin.ToString());
            var isRegardless = user.VendorCode.Split(‘;‘).Contains("*");

            if (!isAdmin && !isRegardless)
            {
                if (!string.IsNullOrEmpty(user.VendorCode) && user.VendorCode.Contains(";"))
                {
                    var supplierSeries = user.VendorCode.Split(‘;‘);

                    Expression<Func<ImportOrder, bool>> expr1 = o => o.SupplierSeries.Contains(supplierSeries[0]);
                    supplierSeries.ForEach(o => { expr1 = expr1.Or(or => or.SupplierSeries.Contains(o)); });

                    expr = expr.And(expr1);
                }
                else
                {
                    expr = expr.And(o => o.SupplierSeries.Contains(user.VendorCode));
                }
            }
            //调用
            var model = importOrderService.Queryable(expr).OrderByDescending(o=>o.Id).ToPagedList(page, 15);
            ViewBag.Count = model.Count();

            return View(model);
        }
}

  

 

 

时间: 2024-08-03 12:39:19

对IOC模式与容器Autofac在MVC里面的一些用法的相关文章

IOC容器-Autofac在MVC中实现json方式注入使用

在你阅读时,默认已经了解IOC和autofac的基本用法, 我在最近的我的博客项目中运用了IOC autofac 实现了依赖注入 由于我的项目时asp.net MVC所以我目前向大家展示MVC中如何使用autofac 首先在app_start中新建一个类包含以下方法 using System.Reflection; using Autofac; using Autofac.Integration.Mvc; using System.Web.Mvc; using Microsoft.Extensi

依赖注入容器Autofac与MVC集成

Autofac是应用于.Net平台的依赖注入(DI,Dependency Injection)容器,具有贴近.契合C#语言的特点.随着应用系统的日益庞大与复杂,使用Autofac容器来管理组件之间的关系可以"扁平化"错综复杂的类依赖,具有很好的适应性和便捷度.  在该篇博文中,我们将应用Autofac,以依赖注入的方式建立传统ASP.NET页面与服务/中间层之间的联系,建立"呈现"与"控制"的纽带. 那么,如何将依赖注入(Dependency I

Ioc容器Autofac系列(2)-- asp.net mvc中整合autofac(转)

经过上篇蜻蜓点水的介绍后,本篇通过实例快速上手autofac,展示当asp.net mvc引入了autofac之后会带来什么. 创建Asp.net MVC并引入Autofac 首先,创建一个MVC站点,为方便起见,选初始带HomeController和AccountController的那种.然后通过NuGet或到Autofac官网下载来引入类库.个人推荐前者,因为从VS2010开始,已内集可视化的NuGet功能,使用起来非常方便.如下图所示: 这是vs2012的界面,点击"Manage NuG

Ioc容器Autofac系列(1)-- 初窥

前言 第一次接触Autofac是因为CMS系统--Orchard,后来在一个开源爬虫系统--NCrawler中也碰到过,随着深入了解,我越发觉得Ioc容器是Web开发中必不可少的利器.那么,Ioc容器是用来做什么的?用了有什么好处?我相信如果不明白这两点就很难敞开心扉接受Ioc容器. 传统解耦设计的弊端 为方便描述,举个日志的栗子.我简化实现,一个Log类,一个SaveLog方法.如果其他类想拥有记日志功能,那么只需在内部包含一个Log类型的变量: public class Log  {    

Ioc容器Autofac系列(1)-- 初窥(转)

前言 第一次接触Autofac是因为CMS系统--Orchard,后来在一个开源爬虫系统--NCrawler中也碰到过,随着深入了解,我越发觉得Ioc容器是Web开发中必不可少的利器.那么,Ioc容器是用来做什么的?用了有什么好处?我相信如果不明白这两点就很难敞开心扉接受Ioc容器. 传统解耦设计的弊端 为方便描述,举个日志的栗子.我简化实现,一个Log类,一个SaveLog方法.如果其他类想拥有记日志功能,那么只需在内部包含一个Log类型的变量: 双击代码全选 1 2 3 4 5 6 7 8

ASP.NET Core中使用IOC三部曲(二.采用Autofac来替换IOC容器,并实现属性注入)

前言 本文主要是详解一下在ASP.NET Core中,自带的IOC容器相关的使用方式和注入类型的生命周期. 这里就不详细的赘述IOC是什么 以及DI是什么了.. emm..不懂的可以自行百度. 目录 ASP.NET Core中使用IOC三部曲(一.使用ASP.NET Core自带的IOC容器) ASP.NET Core中使用IOC三部曲(二.采用Autofac来替换IOC容器,并实现属性注入) ASP.NET Core中使用IOC三部曲(三.采用替换后的Autofac来实现AOP拦截) 正文 上

ioc初步理解(二) 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

之前在园子闲逛的时候,发现许多关于automapper的文章,以及用aotufac+automapper合在一起用.当然发现大多数文章是将automapper的特点说出或将automapper几处关键代码放出.当然有过基础的人看这种文章没有什么问题,但是对于完全没有基础的小白来看完全是灾难级别的(我就是),经常按着博文一点一点的写,突然发现少了一部分导致代码无法运行.在搜索各种文章之后,终于用自己的理解写出了一个简单的运用automapper的demo,日后待我对automapper理解加深会进

ASP.NET MVC IOC依赖注入之Autofac系列(二)- WebForm当中应用

上一章主要介绍了Autofac在MVC当中的具体应用,本章将继续简单的介绍下Autofac在普通的WebForm当中的使用. PS:目前本人还不知道WebForm页面的构造函数要如何注入,以下在WebForm页面将主要采用属性注入的方式. 接下来我们正式进入主题,在上一章的基础上我们再添加一个web项目TianYa.DotNetShare.WebDemo,首先看我们的解决方案 本demo的web项目为ASP.NET Web 应用程序(.NET Framework 4.5) 空Web窗体,需要引用

Spring IOC容器和Spring MVC IOC容器的区别

web.xml <context-param> <param-name>contextConfigLocation</param-name> <!-- 指定加载application配置文件 --> <param-value>classpath:spring/application.xml</param-value> </context-param> <listener> <listener-class&