标签:
一:对于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