先简单了解一这个几个 名词的意思。
控制反转(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 里面的一个方法 测试一下
可以看到 已经注入成功了 小菜也有梦想。 每天一点点
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Net Core Web Api项目与在NginX下发布的方法
asp.net core3.1 引用的元包dll版本兼容性问题解决方案
IdentityServer4实现.Net Core API接口权限认证(快速入门)
ASP.NET Core MVC通过IViewLocationExpander扩展视图搜索路径的实现
网友评论