标签:
一:对于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); } }
标签:
原文地址:http://www.cnblogs.com/jameswenhe/p/4537988.html