ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下
先简单了解一这个几个 名词的意思。
控制反转(IOC) 依赖注入(DI) 并不是某种技术。 而是一种思想。一种面向对象编程法则
什么是控制反转(IOC)? 什么是依赖注入(DI)
可以点击下面链接 理解的比较详细
https://blog.csdn.net/PacosonSWJTU/article/details/52786216
https://www.cnblogs.com/Mr-Rocker/p/7721824.html
控制反转(IOC)
在之前传统应用程序 我们都是在类内部主动实例化依赖对象,从而导致类与类之间高耦合,难于测试
可以看到下图类与类之间 依赖关系很紧密
(图是我盗的。感谢做这个图的大佬)
IOC 就是一种容器 把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是 松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
IOC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。
依赖注入(DI)
依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台
依赖谁? 依赖于IOC容器
注入谁 ? 由IoC容器注入应用程序某个对象,应用程序依赖的对象;
被依赖者并不是有依赖者主动去初始化 而是有提供资源的外部创建者决定
两者关系也就是 被注入对象依赖IoC容器配置依赖对象
说到DI IOC 就有必要了解下 现在用的最多的AutoFac
首先在项目中引入 AutoFac 如果你是WebAPI 你可以输入 AutoFac.WebApi2
我定义了 两个仓储类 IRepositoryBase 和 RepositoryBase 主要用于操作数据库的各种方法
public interface IRepositoryBase<T> where T:class { IQueryable<T> FindAll(); T FindSingle(Expression<Func<T, bool>> exp = null); T Find(int id); IQueryable<T> Find(Expression<Func<T, bool>> exp = null); /// <summary> /// Linq表达式树查询分页 /// </summary> /// <returns></returns> IQueryable<T> Find(int pageindex = 1, int pagesize = 10, Expression<Func<T, bool>> exp = null); /// <summary> /// 得到受影响条数 /// </summary> /// <returns></returns> int GetCount(Expression<Func<T, bool>> exp = null); void Add(T entity); void AddBatch(T[] entitys); void AddBatch(List<T> entitys); /// <summary> /// 更新实体所有属性 /// </summary> /// <returns></returns> void Update(T entity); void Delete(T entity); /// <summary> /// 按指定的ID进行批量更新 /// </summary> void Update(Expression<Func<T, object>> identityExp,T entity); T Update(T entity,int id); /// <summary> /// 批量删除 /// </summary> void Delete(Expression<Func<T, bool>> exp); void Save(); int ExecuteSql(string sql); }
继承接口并实现
public class RepositoryBase<T> : IRepositoryBase<T> where T:class { protected OpenSPDBContext openSPDBContext = new OpenSPDBContext(); public void Add(T entity) { openSPDBContext.Set<T>().Add(entity); Save(); } public void AddBatch(T[] entitys) { openSPDBContext.Set<T>().AddRange(entitys); Save(); } public void Delete(Expression<Func<T, bool>> exp) { var entitys= openSPDBContext.Set<T>().Where(exp); openSPDBContext.Set<T>().RemoveRange(entitys); } public void Delete(T entity) { openSPDBContext.Set<T>().Remove(entity); Save(); } public int ExecuteSql(string sql) { return openSPDBContext.Database.ExecuteSqlCommand(sql); } public IQueryable<T> Find(Expression<Func<T, bool>> exp = null) { return Filter(exp); } public T Find(int id) { return openSPDBContext.Set<T>().Find(id); } public IQueryable<T> Find(int pageindex, int pagesize, Expression<Func<T, bool>> exp = null) { return Filter(exp).Skip(pagesize * (pageindex - 1)).Take(pagesize); } public IQueryable<T> FindAll() { return openSPDBContext.Set<T>(); } public T FindSingle(Expression<Func<T, bool>> exp = null) { return openSPDBContext.Set<T>().AsNoTracking().FirstOrDefault(exp); } public int GetCount(Expression<Func<T, bool>> exp = null) { return Filter(exp).Count(); } public void Update(T entity) { openSPDBContext.Entry(entity).State = EntityState.Modified; Save(); } /// <summary> /// 按指定id更新实体,会更新整个实体 /// </summary> /// <param name="identityExp">The identity exp.</param> /// <param name="entity">The entity.</param> public void Update(Expression<Func<T, object>> identityExp, T entity) { openSPDBContext.Set<T>().AddOrUpdate(identityExp, entity); } public IQueryable<T> Filter(Expression<Func<T,bool>> exp) { var dbset = openSPDBContext.Set<T>().AsQueryable(); if (exp != null) dbset = dbset.Where(exp); return dbset; } public void Save() { try { openSPDBContext.SaveChanges(); } catch (DbEntityValidationException e) { throw new Exception(e.EntityValidationErrors.First().ValidationErrors.First().ErrorMessage); throw; } } public void AddBatch(List<T> entitys) { openSPDBContext.Set<T>().AddRange(entitys); } public T Update(T entity, int id) { openSPDBContext.Entry(entity).State = EntityState.Modified; Save(); return openSPDBContext.Set<T>().Find(id); } }
然后 在全局类中注册依赖配置
我新建了个逻辑处理层 Server 用来方便控制调用 这里我依赖了IRepositoryBase<T>
public class ShopingServer : IShopingServer { private IRepositoryBase<ShopingInfo> _shopingRepository; public ShopingServer(IRepositoryBase<ShopingInfo> shopingRepository) { _shopingRepository = shopingRepository; } public IQueryable<ShopingInfo> GetAll() { var ss = _shopingRepository.FindAll(); return ss; } }
然后控制器 注入 (这里 我依赖了IRepositoryBase IShopingServer) IShopingServer 是我定义的服务类接口 这里我就不贴出来了
我们 分别调用一下 IRepositoryBase IShopingServer 里面的一个方法 测试一下
可以看到 已经注入成功了 小菜也有梦想。 每天一点点