依赖注入(ID)是一种实现对象及其合作者或者依赖想之间松散耦合的技术
对于传统的方法来说,获取类的方法通常用new如下
1 public class DIController : Controller 2 { 3 public IActionResult Index() 4 { 5 MyServices my = new MyServices(); 6 my.getName(); 7 return View(); 8 } 9 }
但是问题来了,如果我后期要修改MyServices类的时候,就需要在整个项目中来搜索修改
一:接口注入
为了实现解耦,我们需要建立IServices的接口,然后类实现接口,在控制器中进行构造函数,初始化接口,然后使用接口来进行操作,这样就达到了解耦的目的,俗称依赖注入
具体类代码如下
1 namespace CoreWeb2.Services 2 { 3 public class MyServices:IServices 4 { 5 public string getName() 6 { 7 return "张三"; 8 } 9 } 10 public class OServices:IServices 11 { 12 public string getName() 13 { 14 return "李四"; 15 } 16 } 17 public interface IServices { 18 string getName(); 19 } 20 }
控制器代码如下:
1 namespace CoreWeb2.Controllers 2 { 3 public class DIController : Controller 4 { 5 /// <summary> 6 /// 通过构造函数初始化接口 7 /// 在外界使用时候直接new出具体类,这样就达到了程序解耦的目的,俗称依赖注入 8 /// </summary> 9 public IServices _services; 10 public DIController(IServices services) 11 { 12 this._services = services; 13 } 14 public IActionResult Index() 15 { 16 //通过接口调用 17 _services.getName(); 18 return View(); 19 } 20 } 21 }
但是问题又来了,因为控制器默认构造函数是一个无参的,现在增加了参数传递,直接访问会报错误,因而就需要在Startup.cs中的ConfigureServices方法中进行程序注入,将构造函数的参数注入到容器中,当程序访问时会自动在容器中找参数,才可以使用
依赖注入有三种方式:
1、AddTransient
每个请求创建一个
2、AddScoped
一个域创建一个
3、AddSingleton
单例,整个应用程序生命周期以内只创建一个实例
1 //每个请求创建一个 2 services.AddTransient<IServices, MyServices>(); 3 //一个域创建一个 4 services.AddScoped<IServices, MyServices>(); 5 //单例,整个应用程序生命周期以内只创建一个实例 6 services.AddSingleton<IServices, MyServices>();
当程序进行依赖注入后,控制器中就可以访问到当前的实例对象了,
二:泛型注入
泛型接口
/// <summary> /// 数据仓储 /// </summary> /// <typeparam name="TEntity"></typeparam> public interface IRepository<TEntity> where TEntity : class { DbContext DbContext { get; } DbSet<TEntity> Entities { get; } IQueryable<TEntity> Table { get; } TEntity GetById(object id); void Insert(TEntity engine, bool isSave = true); void Update(TEntity engine, bool isSave = true); void Delete(TEntity engine, bool isSave = true); }
泛型接口实现
public class EfRepository<TEntity> : IRepository<TEntity> where TEntity:class { private GeneralDbContext _dbContext; public EfRepository(GeneralDbContext generalDbContext) { _dbContext = generalDbContext; } public DbContext DbContext => _dbContext; public DbSet<TEntity> Entities => _dbContext.Set<TEntity>(); public IQueryable<TEntity> Table => Entities; public void Delete(TEntity engine, bool isSave = true) { Entities.Remove(engine); if (isSave) { _dbContext.SaveChanges(); } } public TEntity GetById(object id) { return _dbContext.Set<TEntity>().Find(id); } public void Insert(TEntity engine, bool isSave = true) { Entities.Add(engine); if (isSave) { _dbContext.SaveChanges(); } } public void Update(TEntity engine, bool isSave = true) { Entities.Update(engine); if (isSave) { _dbContext.SaveChanges(); } }
泛型注入方式
//将泛型注入 services.AddScoped(typeof(IRepository<>),typeof(EfRepository<>));
关联类GeneralDbContext
public class GeneralDbContext : DbContext { public GeneralDbContext(DbContextOptions options) : base(options) { } public DbSet<Category> Categorys{ get; set; } }