ADO.NET

 

一、ADO.NET概要

ADO.NET是.NET框架中的重要组件,主要用于完成C#应用程序访问数据库

二、ADO.NET的组成

①System.Data  → DataTable,DataSet,DataRow,DataColumn,DataRelation,Constraint,DataColumnMapping,DataTableMapping

②System.Data.Coummon     → 各种数据访问类的基类和接口

③System.Data.SqlClient   → 对Sql Server进行操作的数据访问类

  1. 主要有:   a) SqlConnection            数据库连接器
  1.             b) SqlCommand               数据库命名对象
  1.             c) SqlCommandBuilder        生存SQL命令
  1.             d) SqlDataReader            数据读取器
  1.             e) SqlDataAdapter           数据适配器,填充DataSet
  1.             f) SqlParameter             为存储过程定义参数
  1.             g) SqlTransaction           数据库事物

三、Connection连接对象

Connection对象也称为数据库连接对象,Connection对象的功能是负责对数据源的连接。所有Connection对象的基类都是DbConnection类。

3.1、连接字符串

基本语法:数据源(Data Source)+数据库名称(Initial Catalog)+用户名(User ID)+密码(Password)

3.1.1、SQL Server连接字符串

Data Source=.;Initial Catalog=myDataBase;User Id=myUsername;Password=myPassword;

3.1.2、Access连接字符串

Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\myDatabase.mdb;User Id=admin;Password=;

3.1.3、MySQL连接字符串

Server=myServerAddress;Database=myDatabase;Uid=myUsername;Pwd=myPassword;

3.1.4、DB2连接字符串

Server=myAddress:myPortNumber;Database=myDatabase;UID=myUsername;PWD=myPassword;

3.1.5、Oracle连接字符串

Data Source=TORCL;User Id=myUsername;Password=myPassword;

在VS中获得连接字符串并连接到数据库:工具->连接到数据库

3.2、连接到数据库

Connection对象有两个重要属性:

(1)ConnectionString:表示用于打开 SQL Server 数据库的字符串; 
(2)State:表示 Connection 的状态,有Closed和Open两种状态。

Connection对象有两个重要方法:

(1)Open()方法:指示打开数据库;

(2)Close()方法:指示关闭数据库。

四、Command对象

Command对象也称为数据库命令对象,Command对象主要执行包括添加、删除、修改及查询数据的操作的命令。也可以用来执行存储过程。用于执行存储过程时需要将Command对象的CommandType 属性设置为CommandType.StoredProcedure,默认情况下CommandType 属性为CommandType.Text,表示执行的是普通SQL语句。

Command主要有三个方法:

4.1、ExecuteNonQuery

ExecuteNonQuery()执行一个非查询SQL语句,返回受影响的行数,这个方法主要用于执行对数据库执行增加、更新、删除操作,注意查询的时候不是调用这个方法。用于完成insert,delete,update操作。执行时返回影响行数。

using 关键字有两个主要用途:
  (
).作为指令,用于为命名空间创建别名或导入其他命名空间中定义的类型。
  (
).作为语句,用于定义一个范围,在此范围的末尾将释放对象。

using只能用于实现了IDisposable接口的类型,禁止为不支持IDisposable接口的类型使用using语句,否则会出现编译错误;

4.1.1、拼接字符串
string str = string.Format("Data Source={0};Initial Catalog={1};User ID={2};Password={3}", txtSQLAdd.Text, txtSqlName.Text, txtUser.Text, txtPwd.Text);

4.1.2、参数

如果直接拼接字符串会存在安全隐患,使用参数可以解决问题。

4.1.3、增加、删除、修改

这里的示例是insert,如果想执行delete与update代码是一样的,只是变化了SQL。

增加:insert [into] <表名> (列名) values (列值)     例:insert into Strdents (姓名,性别,出生日期) values ('开心朋朋','男','1980/6/15')

删除:delete from <表名> [where <删除条件>]    例:delete from a where name='开心朋朋'(删除表a中列值为开心朋朋的行)

修改:update <表名> set <列名=更新值> [where <更新条件>]    例:update tongxunlu set 年龄=18 where 姓名='蓝色小名'

4.2ExecuteScalar ()

ExecuteScalar ()从数据库检索单个值。这个方法主要用于统计操作。ExecuteScalar ()这个方法是针对SQL语句执行的结果是一行一列的结果集,这个方法只返回查询结果集的第一行第一列。针对SQL聚合函数(count,max,min,avg,sum)使用。

聚合函数:select count(*) from <表名>

可能返回NULL值,需要对结果进行判断。

  1. if (object.Equals(my,null))  //可以使用Equals进行Null值的判断,易读性强
  1.   Console.WriteLine("Not Data");
  1. else
  1.   Console.WriteLine("Yes");

五、ExecuteReader获得数据

ExecuteReader用于实现只进只读的高效数据查询。用来读取一个数据表。用于查询一个数据表。

ExecuteReader:返回一个SqlDataReader对象,可以通过这个对象检查查询结果。它提供的是只进只读的执行方式,读取一行之后,移动到下一行,上一行的数据就不能使用了。手动调用Read()方法之后,SqlDataReader对象才会移到结果集的第一行。Read()方法会返回一个bool值,True则下行可用,false表示下行不可用。

5.1、使用ExecuteReader实现数据查询

  1. //执行查询返回结果集
  1.                 SqlDataReader sdr = cmd.ExecuteReader();
  1.                 //下移游标,读取一行,如果没有数据了则返回false
  1.                 while (sdr.Read())
  1.                 {
  1.                     Console.WriteLine("编号:" + sdr["Id"] + ",车名:" + sdr["Title"] + ",速度:" + sdr["Speed"]);
  1.                 }

5.2、实体类

实体类用于封装及映射数据。

5.3DataGridView展示数据

定义一个表示对象的类

定义一个对象的列表

初始化一个对象,用sqlReader()将数据读出后存入对象。

把对象加入对象列表中。

对象列表与DataGridView 显示。

窗口间的传值

一个窗口定义一个对象【1】

在另外一个窗口定义一个对象2

显示窗口的时候把1赋值给2

在窗口2加载的时候把2的属性显示出来

  上一篇,我们介绍了如何读取自定义的json文件,数据是读取出来了,只是处理的时候太麻烦,需要一遍一遍写,很枯燥.那么有没有很好的办法呢?经过钻研,办法有了.

  既然一个一个读取比较麻烦,那么可以把它放入一个类里面么?当然可以.这样直接注入这个类,让控制器去读取,那么就不需要每次加载它了,一次加载就可以在任何地方使用了.

  由于本文是接这上一篇文章的更新介绍,请先读取上一篇文章再浏览此篇文章

(1):在Models文件夹中添加类Class,并填写如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace CoreDemo.Models
{
    public class Class
    {
        public int ClassNum { getset; }
        public string ClassName { getset; }
        public List<Student> Students { getset; }
    }
    public class Student
    {
        public string name { getset; }
        public int age { getset; }
    }
}

(2):更新Startup.cs脚本,更新函数ConfigureServices:

1
2
3
4
5
6
public void ConfigureServices(IServiceCollection services)
       {
           var classSetting = JsonConvert.DeserializeObject<Class>(File.ReadAllText("JsonFile/class.json"));
           services.AddSingleton(classSetting);//全局注入
           services.AddMvc();
       }

(3):更新Home控制器,将配置类注入进来并使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class HomeController : Controller
   {
       private readonly Class _classSetting;
       public HomeController(Class classSetting)
       {
           _classSetting = classSetting;
       }
 
       public IActionResult Index()
       {
           return Content("班级编号="+ _classSetting.ClassNum + ",班级名称="+ _classSetting.ClassName + "\r"
               +"学生名称="+ _classSetting.Students[0].name+",学生年纪="+ _classSetting.Students[0].age
           );
       }
   }

(4):运行项目,查看运行结果,成功:

总结:如果将配置文件一个一个读取的话是可行的,只是太麻烦,如果其他地方也需要用到的话又需要再次加载读取,浪费开发效率与运行效率.直接以类的方式加载并注入,可以让它在每个地方运行,消耗最少,效率最高.

查了下 转PDF的各种框架   发现大部分都是收费的。 发现一款免费的iTextSharp  就想玩一下

只是简单做个HTML 转PDF  没有过深的探究。

首先 我在项目中引入iTextSharp   还是老方法 要么 NuGet上下载 或者 直接命令

然后在项目中建了一个HTML   里面就是一些简单的标签 和一些占位符

然后建了个PDF帮助类  里面实现具体转换的方法

  1. public class PDFHelp
  2. {
  3. public byte[] ConvertHtmlTextToPDF(string htmltext)
  4. {
  5. if (string.IsNullOrEmpty(htmltext))
  6. {
  7. return null;
  8. }
  9. //避免htmlText没有任何html tag标签的純文字时,转PDF时会挂掉,所以一律加上<p>标签
  10. //htmlText = "<p>" + htmltext + "</p>";
  11.  
  12. MemoryStream stream = new MemoryStream();
  13. byte[] data = Encoding.UTF8.GetBytes(htmltext);
  14. MemoryStream msInput = new MemoryStream(data);
  15. Document doc = new Document();
  16. PdfWriter writer = PdfWriter.GetInstance(doc, stream);
  17. //指定文件默认缩放标准100%
  18. PdfDestination pdfDest = new PdfDestination(PdfDestination.XYZ, 0, doc.PageSize.Height, 1f);
  19. doc.Open();
  20. //使用XMLWorkerHelper把Html parse到PDF
  21. XMLWorkerHelper .GetInstance().ParseXHtml(writer, doc, msInput, null, Encoding.UTF8, new UnicodeFontFactory());
  22. //將pdfDest 写入到PDF
  23. PdfAction action = PdfAction.GotoLocalPage(1, pdfDest, writer);
  24. writer.SetOpenAction(action);
  25. doc.Close();
  26. msInput.Close();
  27. stream.Close();
  28. //回传PDF
  29. return stream.ToArray();
  30. }
  31. }

占位符的简单替换 测试下。只写了三个 举个例子

  1. public string Placeholderfill(string htmlContext)
  2. {
  3. var entity = _shopingRepository.FindAll().FirstOrDefault();
  4. htmlContext = htmlContext.Replace("{{SHOPINGNAME}}", entity.ShopingName);
  5. htmlContext = htmlContext.Replace("{{SHOPINGPric}}", entity.ShopingPric.ToString());
  6. htmlContext = htmlContext.Replace("{{SHOPINGNuber}}", entity.ShopingCount.ToString());
  7. return htmlContext;
  8. }

接下了就是控制器 的调用了

  1. public FileResult ExportPDF()
  2. {
  3. string htmlContext = System.IO.File.ReadAllText(Server.MapPath("~/HTMLTemplate/ShopingBuy.html"));
  4. var context= _iShopingServer.Placeholderfill(htmlContext);
  5. PDFHelp pf = new PDFHelp();
  6. var ms= pf.ConvertHtmlTextToPDF(context);
  7. return File(ms,"application/pdf", "shoping"+ DateTime.Now+ ".pdf");
  8. }

在页面上写个点击PDF下载的按钮 Ajax 调用这个方法  然后就是最终实现的效果。 写的很粗糙。 但实现的过程还是比较容易的。

一般业务都是转PDF然后加入邮箱附件 用来发邮件的。

这里只是简单实现。  有时间还得继续深入研究

先简单了解一这个几个 名词的意思。

控制反转(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  主要用于操作数据库的各种方法

  1. public interface IRepositoryBase<T> where T:class
  2. {
  3.  
  4. IQueryable<T> FindAll();
  5.  
  6. T FindSingle(Expression<Func<T, bool>> exp = null);
  7.  
  8. T Find(int id);
  9.  
  10. IQueryable<T> Find(Expression<Func<T, bool>> exp = null);
  11.  
  12. /// <summary>
  13. /// Linq表达式树查询分页
  14. /// </summary>
  15. /// <returns></returns>
  16. IQueryable<T> Find(int pageindex = 1, int pagesize = 10, Expression<Func<T, bool>> exp = null);
  17.  
  18. /// <summary>
  19. /// 得到受影响条数
  20. /// </summary>
  21. /// <returns></returns>
  22. int GetCount(Expression<Func<T, bool>> exp = null);
  23.  
  24. void Add(T entity);
  25.  
  26. void AddBatch(T[] entitys);
  27.  
  28. void AddBatch(List<T> entitys);
  29.  
  30. /// <summary>
  31. /// 更新实体所有属性
  32. /// </summary>
  33. /// <returns></returns>
  34. void Update(T entity);
  35.  
  36. void Delete(T entity);
  37.  
  38. /// <summary>
  39. /// 按指定的ID进行批量更新
  40. /// </summary>
  41. void Update(Expression<Func<T, object>> identityExp,T entity);
  42.  
  43. T Update(T entity,int id);
  44.  
  45. /// <summary>
  46. /// 批量删除
  47. /// </summary>
  48. void Delete(Expression<Func<T, bool>> exp);
  49.  
  50. void Save();
  51.  
  52. int ExecuteSql(string sql);
  53. }

继承接口并实现

  1. public class RepositoryBase<T> : IRepositoryBase<T> where T:class
  2. {
  3. protected OpenSPDBContext openSPDBContext = new OpenSPDBContext();
  4.  
  5. public void Add(T entity)
  6. {
  7. openSPDBContext.Set<T>().Add(entity);
  8. Save();
  9. }
  10.  
  11. public void AddBatch(T[] entitys)
  12. {
  13. openSPDBContext.Set<T>().AddRange(entitys);
  14. Save();
  15. }
  16.  
  17. public void Delete(Expression<Func<T, bool>> exp)
  18. {
  19. var entitys= openSPDBContext.Set<T>().Where(exp);
  20. openSPDBContext.Set<T>().RemoveRange(entitys);
  21. }
  22.  
  23. public void Delete(T entity)
  24. {
  25. openSPDBContext.Set<T>().Remove(entity);
  26. Save();
  27. }
  28.  
  29. public int ExecuteSql(string sql)
  30. {
  31. return openSPDBContext.Database.ExecuteSqlCommand(sql);
  32. }
  33.  
  34. public IQueryable<T> Find(Expression<Func<T, bool>> exp = null)
  35. {
  36. return Filter(exp);
  37. }
  38.  
  39. public T Find(int id)
  40. {
  41. return openSPDBContext.Set<T>().Find(id);
  42. }
  43.  
  44. public IQueryable<T> Find(int pageindex, int pagesize, Expression<Func<T, bool>> exp = null)
  45. {
  46.  
  47. return Filter(exp).Skip(pagesize * (pageindex - 1)).Take(pagesize);
  48. }
  49.  
  50. public IQueryable<T> FindAll()
  51. {
  52. return openSPDBContext.Set<T>();
  53. }
  54.  
  55. public T FindSingle(Expression<Func<T, bool>> exp = null)
  56. {
  57. return openSPDBContext.Set<T>().AsNoTracking().FirstOrDefault(exp);
  58. }
  59.  
  60. public int GetCount(Expression<Func<T, bool>> exp = null)
  61. {
  62. return Filter(exp).Count();
  63. }
  64.  
  65. public void Update(T entity)
  66. {
  67. openSPDBContext.Entry(entity).State = EntityState.Modified;
  68. Save();
  69. }
  70.  
  71. /// <summary>
  72. /// 按指定id更新实体,会更新整个实体
  73. /// </summary>
  74. /// <param name="identityExp">The identity exp.</param>
  75. /// <param name="entity">The entity.</param>
  76. public void Update(Expression<Func<T, object>> identityExp, T entity)
  77. {
  78. openSPDBContext.Set<T>().AddOrUpdate(identityExp, entity);
  79. }
  80.  
  81. public IQueryable<T> Filter(Expression<Func<T,bool>> exp)
  82. {
  83. var dbset = openSPDBContext.Set<T>().AsQueryable();
  84. if (exp != null)
  85. dbset = dbset.Where(exp);
  86.  
  87. return dbset;
  88.  
  89. }
  90.  
  91. public void Save()
  92. {
  93. try
  94. {
  95. openSPDBContext.SaveChanges();
  96. }
  97. catch (DbEntityValidationException e)
  98. {
  99. throw new Exception(e.EntityValidationErrors.First().ValidationErrors.First().ErrorMessage);
  100. throw;
  101. }
  102. }
  103.  
  104. public void AddBatch(List<T> entitys)
  105. {
  106. openSPDBContext.Set<T>().AddRange(entitys);
  107. }
  108.  
  109. public T Update(T entity, int id)
  110. {
  111. openSPDBContext.Entry(entity).State = EntityState.Modified;
  112. Save();
  113. return openSPDBContext.Set<T>().Find(id);
  114. }
  115. }

然后 在全局类中注册依赖配置

我新建了个逻辑处理层 Server  用来方便控制调用   这里我依赖了IRepositoryBase<T>

  1. public class ShopingServer : IShopingServer
  2. {
  3. private IRepositoryBase<ShopingInfo> _shopingRepository;
  4. public ShopingServer(IRepositoryBase<ShopingInfo> shopingRepository)
  5. {
  6. _shopingRepository = shopingRepository;
  7. }
  8.  
  9. public IQueryable<ShopingInfo> GetAll()
  10. {
  11. var ss = _shopingRepository.FindAll();
  12. return ss;
  13. }
  14. }

然后控制器  注入  (这里 我依赖了IRepositoryBase  IShopingServer)  IShopingServer 是我定义的服务类接口 这里我就不贴出来了

我们 分别调用一下 IRepositoryBase   IShopingServer  里面的一个方法 测试一下

可以看到 已经注入成功了    小菜也有梦想。 每天一点点

1、InstancePerDependency

对每一个依赖或每一次调用创建一个新的唯一的实例。这也是默认的创建实例的方式。

2、InstancePerLifetimeScope

在一个生命周期域中,每一个依赖或调用创建一个单一的共享的实例,且每一个不同的生命周期域,实例是唯一的,不共享的。

3、InstancePerMatchingLifetimeScope

在一个做标识的生命周期域中,每一个依赖或调用创建一个单一的共享的实例。打了标识了的生命周期域中的子标识域中可以共享父级域中的实例。若在整个继承层次中没有找到打标识的生命周期域,则会抛出异常:DependencyResolutionException。

4、InstancePerOwned

在一个生命周期域中所拥有的实例创建的生命周期中,每一个依赖组件或调用Resolve()方法创建一个单一的共享的实例,并且子生命周期域共享父生命周期域中的实例。若在继承层级中没有发现合适的拥有子实例的生命周期域,则抛出异常:DependencyResolutionException。

5、SingleInstance

每一次依赖组件或调用Resolve()方法都会得到一个相同的共享的实例。其实就是单例模式。

6、InstancePerHttpRequest

在一次Http请求上下文中,共享一个组件实例。仅适用于asp.net mvc开发。

什么是AutoMapper?

简单来说就是将一个对象映射到另一个对象的代码。 摆脱了繁琐的赋值过程 (最常见也就是Model -——ViewModel)

AutoMapper安装

我使用的是VS2015   可以在NuGet中直接输入AutoMapper 去下载

也可以使用控制台命令

PM> Install-Package AutoMapper

这里我定义了两个类   ShopingInfo         ShopingInfoViewModel

  1. public class ShopingInfo:EntityBase
  2. {
  3.  
  4. public string ShopingName { get; set; }
  5.  
  6. public int ShopingCount { get; set; }
  7.  
  8. public decimal ShopingPric { get; set; }
  9.  
  10. public int Stock { get; set; }
  11.  
  12. public int Volumeofvolume { get; set; }
  13.  
  14. public int ShopingTypeId { get; set; }
  15.  
  16. public virtual ShopingType ShopingType { get; set; }
  17. }
  1. public class ShopingInfoViewModel
  2. {
  3. public int ID { get; set; }
  4.  
  5. public string ShopingName { get; set; }
  6.  
  7. public int ShopingCount { get; set; }
  8.  
  9. public decimal ShopingPric { get; set; }
  10.  
  11. public int Stock { get; set; }
  12.  
  13. public int Volumeofvolume { get; set; }
  14.  
  15. public string ShopingTypeName { get; set; }
  16. }

需要用到的命名空间

using AutoMapper;

然后 专门建了一个类用来存放这些映射关系SourceProfile 并且继承了 Profile

  1. public class SourceProfile : Profile
  2. {
  3. public SourceProfile()
  4. {
  5. base.CreateMap<ShopingInfo, ShopingInfoViewModel>();
  6. }
  7. }

如果 我们发现两类中有字段名不一致。

例如 我吧shopingInfoViewModel 中的 ShopingName  改为  Name    那你可以这样写

  1. public class SourceProfile : Profile
  2. {
  3. public SourceProfile()
  4. {
  5. base.CreateMap<ShopingInfo, ShopingInfoViewModel>();
  6.  
  7. // base.CreateMap<ShopingInfo, ShopingInfoViewModel>().ForMember(x => x.Name,
  8. // q => { q.MapFrom(z => z.ShopingName);
  9. // });
  10. }
  11. }

建了个中间类 用来封装上面的代码

  1. public class AutoMapper
  2. {
  3. public static void Start()
  4. {
  5. Mapper.Initialize(x =>
  6. {
  7. x.AddProfile<SourceProfile>();
  8. });
  9. }
  10. }

然后就在全局类Global中 使得 启动初始化就去加载 加入下面这句代码

  1. AutoMapper.Start();
  2.  
  3. 好了。 基本的都搞好了。 现在测试一下

  1. 可以 看到 已经映射上去了。
  2.  
  3. 如果对多个Profile派生类的AutoMapper有疑问,可以这么写:
1
2
3
4
5
//配置映射
            AutoMapper.Mapper.Initialize(map => map.AddProfiles(new[] {
                typeof(Dto_StudentProfile),
                typeof(StudentProfile)
            }));
  1.  
  2. 其中Dto_StudentProfileStudentProfile是两个Profile的派生类,写了不同字段名称,不同类型的互相映射,如果还有疑问,可以移步我的博客C#使用AutoMapper6.2.2.0进行对象映射

ADO.NET .net core2.0添加json文件并转化成类注入控制器使用 简单了解 iTextSharp实现HTML to PDF ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下 C# AutoMapper 了解一下的更多相关文章

  1. .net core2.0添加json文件并转化成类注入控制器使用 让js调试更简单—console

    .net core2.0添加json文件并转化成类注入控制器使用 上一篇,我们介绍了如何读取自定义的json文件,数据是读取出来了,只是处理的时候太麻烦,需要一遍一遍写,很枯燥.那么有没有很好的办法呢 ...

  2. .net core2.0添加json文件并转化成类注入控制器使用

    上一篇,我们介绍了如何读取自定义的json文件,数据是读取出来了,只是处理的时候太麻烦,需要一遍一遍写,很枯燥.那么有没有很好的办法呢?经过钻研,办法有了. 既然一个一个读取比较麻烦,那么可以把它放入 ...

  3. ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下

    先简单了解一这个几个 名词的意思. 控制反转(IOC) 依赖注入(DI) 并不是某种技术. 而是一种思想.一种面向对象编程法则 什么是控制反转(IOC)?  什么是依赖注入(DI) 可以点击下面链接 ...

  4. ASP.NET Core中的依赖注入(1):控制反转(IoC)

    ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了"标准化&qu ...

  5. 依赖注入 DI 控制反转 IOC MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  6. 浅析“依赖注入(DI)/控制反转(IOC)”的实现思路

    开始学习Spring的时候,对依赖注入(DI)——也叫控制反转(IOC)—— 的理解不是很深刻.随着学习的深入,也逐渐有了自己的认识,在此记录,也希望能帮助其他入门同学更深入地理解Spring.本文不 ...

  7. 依赖注入 DI 控制反转 IOC 概念 案例 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  8. ASP.NET中IOC容器Autofac(依赖注入DI 控制反转IOC)

    IOC的一个重点是在程序运行中,动态的向某个对象提供它所需要的其他对象.这一点是通过DI来实现的.Autofac则是比较流行的一款IOC容器. IoC和DI有什么关系呢?其实它们是同一个概念的不同角度 ...

  9. ASP.NET Core 在 JSON 文件中配置依赖注入

    前言 在上一篇文章中写了如何在MVC中配置全局路由前缀,今天给大家介绍一下如何在在 json 文件中配置依赖注入. 在以前的 ASP.NET 4+ (MVC,Web Api,Owin,SingalR等 ...

随机推荐

  1. Unity笔记(3)自学第二天

    学习记录: 界面使用: 脚本使用: 脚本注意点:

  2. 个人作业-Alpha测试

    课程 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/ 作业要求 https://edu.cnblogs.com/campu ...

  3. TypeError: slice indices must be integers or None or have an __index__ method

    由于除法/自动产生的类型是浮点型,因此出现上述错误,修正方法为,将/更改为// roi_gray_lwpCV = gray_lwpCV[y:y + h // 2, x:x + w] # 检出人脸区域后 ...

  4. ORACLE 字符串补零

    标准函数Lpad 可以实现左补零,但是如果多于需要长度,则会截断字符串.如下:-----------------------情况一:需要补零.       SELECT LPAD ('1234' , ...

  5. Spartan6系列之器件详细介绍、选型参考

    1.      概述 Spartan6系列是一类低成本高容量的FPGA,采用45nm低功耗敷铜技术,能在功耗.性能.成本之间很好地平衡:Spartan6系列内部采用双寄存器.6输入的LUT,还有一系列 ...

  6. 计算机网络(四)--全世界最好的TCP基础知识讲解

    TCP传输的数据单元是报文段,报文段分为首部.数据两部分 TCP首部 首部的前20字节是固定长度,后面的4n字节根据需要增加的选项 字段解释:图中标示单位为bit,不是byte 1.源端口.目的端口: ...

  7. 比较synchronized和读写锁

    一.科普定义 这篇博文的两个主角“synchronized”和“读写锁” 1)synchronized 这个同步关键字相信大家都用得比较多,在上一篇“多个线程之间共享数据的方式”中也详细列举他的应用, ...

  8. mybatis传参总结

    注:文章引用部分 mybatis传递参数总结文章内容 一.单个参数 1.基本数据类型 (1)直接使用 List<ChargeRuleDO> tests(long id); <sele ...

  9. [Algorithm] 11. Linked List Cycle

    Description Given a linked list, determine if it has a cycle in it. To represent a cycle in the give ...

  10. [luogu4056 JSOI2009] 火星藏宝图 (贪心 dp)

    传送门 Solution 一个显然的贪心:选的点数越多越好.这个随便推推就知道了. 那么我们就贪心的从一列上挑最靠下的转移 直接转移不斜率优化复杂度\(O(nm)\),吸一口O2过了... Code ...