添加EF上下文对象,添加接口、实现类以及无处不在的依赖注入(DI)
添加EF上下文对象,添加接口、实现类以及无处不在的依赖注入(DI)
目录索引
简介
上一章,我们介绍了安装和新建控制器、视图,这一章我们来创建个数据模型,并且添加接口和实现类。
添加EF上下文对象
按照我们以前的习惯,我们还是新建几个文件夹
Commons:存放帮助类
Domians:数据模型
Services:接口和实现类

我们在Domains文件夹下添加一个类库 Domain

我们新建一个类 ApplicationDbContext 继承 DbContext

1 using Microsoft.EntityFrameworkCore;
2
3 namespace Domain
4 {
5 public class ApplicationDbContext : DbContext
6 {
7 public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
8 : base(options)
9 {
10 }
11
12 protected override void OnModelCreating(ModelBuilder builder)
13 {
14 base.OnModelCreating(builder);
15 }
16 }
17 }

说明:
DbContext 需要引用 Microsoft.EntityFrameworkCore
第一种方式:选中 DbContext 通过组合键 Ctrl+. 添加 Microsoft.EntityFrameworkCore 引用
第二种方式:在Domain 类库的 project.json 中添加 Microsoft.EntityFrameworkCore 引用
然后,我们打开 \src\Startu.cs 修改 ConfigureServices(IServiceCollection services) 方法,增加对EF的支持(黄色高亮):

1 // This method gets called by the runtime. Use this method to add services to the container.
2 public void ConfigureServices(IServiceCollection services)
3 {
4 // Add framework services.
5 services.AddApplicationInsightsTelemetry(Configuration);
6
7 services.AddDbContext<ApplicationDbContext>(options =>options.UseSqlServer(Configuration.GetConnectionString("SqlServerConnection")));
8
9 services.AddMvc();
10
11 }

上面的 SqlServerConnection 是我们的数据库连接字符串,它的配置在 \src\appsettings.json 文件中(这个名字让我们想起了appsetting.config):

这样,实际上我们就完成了,但是我们后面会用到,我们目前不操作数据。
添加接口和实现类
我们来添加一个接口和实现类,来看一下Asp.net Core的依赖注入。
我们在Services文件夹下添加一个类库 Service

我们在 Service 类库下,新建 三个文件夹:
IDao:存放基础操作类
IService:存放接口文件
ServiceImp:存放实现类
IDao 我们先不管,我们后面 IRepositorycs和Repositorycs(DDD 领域驱动设计) 会使用到,我们主要是添加一个接口和实现类。为了更好的归类接口和实现类,我们在 IService 和 ServiceImp 文件夹下面分别建立一个文件夹 SysManage 用于存放系统管理接口。
我们在 \IService\SysManage\ 下新建一个接口 IUserManage

1 namespace Service.IService
2 {
3 public interface IUserManage
4 {
5 /// <summary>
6 /// 测试接口
7 /// </summary>
8 /// <returns></returns>
9 string Test();
10 }
11 }

我们在 \ServiceImp\SysManage\ 下新建一个实现类 UserManage

1 namespace Service.ServiceImp
2 {
3 public class UserManage : IService.IUserManage
4 {
5 public string Test()
6 {
7 return "我实现了接口方法Test";
8 }
9 }
10 }

修改 \src\Startu.cs 的 ConfigureServices(IServiceCollection services) 方法,实现注入(黄色高亮):

1 // This method gets called by the runtime. Use this method to add services to the container.
2 public void ConfigureServices(IServiceCollection services)
3 {
4 // Add framework services.
5 services.AddApplicationInsightsTelemetry(Configuration);
6
7 services.AddDbContext<ApplicationDbContext>(options =>options.UseSqlServer(Configuration.GetConnectionString("SqlServerConnection")));
8
9 services.AddMvc();
10
11 // Add application services.
12 services.AddTransient<Service.IService.IUserManage, Service.ServiceImp.UserManage>();
13 }

说明:

调用接口
注入有三种方式:构造器注入、属性注入 和 方法注入。我们在 【无私分享:从入门到精通ASP.NET MVC】 系列中大部分使用的是 属性注入,今天我们使用的是 构造器注入:
我们在 HomeController 中 声明接口
private readonly IUserManage _UserManage;
在控制器构造函数中 添加:
public HomeController(IUserManage UserManage)
{
_UserManage = UserManage;
}
依赖注入框架会自动找到 IUserManage 实现类的实例,赋值给该构造函数
我们在 About 视图中 测试一下:
public IActionResult About()
{
ViewData["Message"] = _UserManage.Test();
return View();
}
Ctrl+F5 运行一下:

说明注入成功!(在Asp.net Core中,我们修改代码后直接保存刷新页面就可以,不再像以前那样 要重新编译生成,这点还是很赞的。)
三种注入方式:
构造器注入
构造器注入就在在构造函数中借助参数将依赖的对象注入到创建的对象之中。如下面的代码片段所示,Foo针对Bar的依赖体现在只读属性Bar上,针对该属性的初始化实现在构造函数中,具体的属性值由构造函数的传入的参数提供。当DI容器通过调用构造函数创建一个Foo对象之前,需要根据当前注册的类型匹配关系以及其他相关的注入信息创建并初始化参数对象。

1: public class Foo
2: {
3: public IBar Bar{get; private set;}
4: public Foo(IBar bar)
5: {
6: this.Bar = bar;
7: }
8: }

除此之外,构造器注入还体现在对构造函数的选择上面。如下面的代码片段所示,Foo类上面定义了两个构造函数,DI容器在创建Foo对象之前首选需要选择一个适合的构造函数。至于目标构造函数如何选择,不同的DI容器可能有不同的策略,比如可以选择参数做多或者最少的,或者可以按照如下所示的方式在目标构造函数上标注一个相关的特性(我们在第一个构造函数上标注了一个InjectionAttribute特性)。

1: public class Foo
2: {
3: public IBar Bar{get; private set;}
4: public IBaz Baz {get; private set;}
5:
6: [Injection]
7: public Foo(IBar bar)
8: {
9: this.Bar = bar;
10: }
11:
12: public Foo(IBar bar, IBaz):this(bar)
13: {
14: this.Baz = baz;
15: }
16: }

属性注入
如果依赖直接体现为类的某个属性,并且该属性不是只读的,我们可以让DI容器在对象创建之后自动对其进行赋值进而达到依赖自动注入的目的。一般来说,我们在定义这种类型的时候,需要显式将这样的属性标识为需要自动注入的依赖属性,以区别于该类型的其他普通的属性。如下面的代码片段所示,Foo类中定义了两个可读写的公共属性Bar和Baz,我们通过标注InjectionAttribute特性的方式将属性Baz设置为自动注入的依赖属性。对于由DI容器提供的Foo对象,它的Baz属性将会自动被初始化。

1: public class Foo
2: {
3: public IBar Bar{get; set;}
4:
5: [Injection]
6: public IBaz Baz {get; set;}
7: }

方法注入
体现依赖关系的字段或者属性可以通过方法的形式初始化。如下面的代码片段所示,Foo针对Bar的依赖体现在只读属性上,针对该属性的初始化实现在Initialize方法中,具体的属性值由构造函数的传入的参数提供。我们同样通过标注特性(InjectionAttribute)的方式将该方法标识为注入方法。DI容器在调用构造函数创建一个Foo对象之后,它会自动调用这个Initialize方法对只读属性Bar进行赋值。在调用该方法之前,DI容器会根据预先注册的类型映射和其他相关的注入信息初始化该方法的参数。

1: public class Foo
2: {
3: public IBar Bar{get; private set;}
4:
5: [Injection]
6: public Initialize(IBar bar)
7: {
8: this.Bar = bar;
9: }
10: }

希望跟大家一起学习Asp.net Core
刚开始接触,水平有限,很多东西都是自己的理解和翻阅网上大神的资料,如果有不对的地方和不理解的地方,希望大家指正!
虽然Asp.net Core 现在很火热,但是网上的很多资料都是前篇一律的复制,所以有很多问题我也暂时没有解决,希望大家能共同帮助一下!
原创文章 转载请尊重劳动成果 http://yuangang.cnblogs.com
添加EF上下文对象,添加接口、实现类以及无处不在的依赖注入(DI)的更多相关文章
- 【无私分享:ASP.NET CORE 项目实战(第二章)】添加EF上下文对象,添加接口、实现类以及无处不在的依赖注入(DI)
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 上一章,我们介绍了安装和新建控制器.视图,这一章我们来创建个数据模型,并且添加接口和实现类. 添加EF上下文对象 按照我们以前 ...
- EF上下文对象线程内唯一性与优化
在一次请求中,即一个线程内,若是用到EF数据上下文对象,就创建一个,这也加是很多人的代码中习惯在使用上下文对象时,习惯将对象建立在using中,也是为了尽早释放上下文对象, 但是如果有一个业务逻辑调用 ...
- EF上下文对象创建之线程内唯一
在一次请求中,即一个线程内,若是用到EF数据上下文对象,就创建一个,那么会造成数据混乱,每次创建的对象执行相应的数据库操作,此同时,其他的EF对象内获得的数据可能已经是“过期”的了.即这个数据已经变动 ...
- ADO.NET .net core2.0添加json文件并转化成类注入控制器使用 简单了解 iTextSharp实现HTML to PDF ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下 C# AutoMapper 了解一下
ADO.NET 一.ADO.NET概要 ADO.NET是.NET框架中的重要组件,主要用于完成C#应用程序访问数据库 二.ADO.NET的组成 ①System.Data → DataTable, ...
- ThinkPHP6源码:从Http类的实例化看依赖注入是如何实现的
ThinkPHP 6 从原先的 App 类中分离出 Http 类,负责应用的初始化和调度等功能,而 App 类则专注于容器的管理,符合单一职责原则. 以下源码分析,我们可以从 App,Http 类的实 ...
- 在.NET Core中处理一个接口多个不同实现的依赖注入问题
前言 近段时间在准备公司的技术分享,所以这段时间将大部分时间放在准备分享内容上去了.博客也就停了一下下. 在.NET Core中处理依赖注入问题时,往往是定义好了一个操作规范的接口,会有N多个基于不同 ...
- 第四节:配置的读取、StartUp类、内置依赖注入和扩展改造
一. 配置的读取 在Asp.Net Core中,有一个 appsettings.json 文件,用于存储相应的配置信息,读取的时,要通过构造函数注入:IConfiguration Configurat ...
- PHP类的反射和依赖注入
/** * Class Point */ class Point { public $x; public $y; /** * Point constructor. * @param int $x ho ...
- Android开源项目发现--- 工具类依赖注入DI篇(持续更新)
通过依赖注入减少View.服务.资源简化初始化,事件绑定等重复繁琐工作 1. AndroidAnnotations(Code Diet) android快速开发框架 项目地址:https://gith ...
随机推荐
- HTML4如何让一个DIV居中对齐?float输入日志标题
float:left,right clear:both 如何让一个DIV居中对齐? 第一步:设置外层的DIV的text-align:center; 第二步:设置里层的DIV的margin:auto 以 ...
- winform使用xml作为数据源
1.新建窗体应用程序 2.拖放DataGridView 3.在bin\Debug中放入XML文件 using System; using System.Collections.Generic; usi ...
- int指令(软件中断指令)
INT(软件中断指令)是CALL指令的一种特殊形式.call指令调用调用的子程序是用户程序的一部分,而INT指令调用的操作系统提供的子程序或者其他特殊的子程序. 中断服务子程序和标准过程的最大区别是 ...
- DataGridview 填写数字
private DataGridViewTextBoxEditingControl CellEdit = null; // 声明 一个 CellEdit private void dgv ...
- 第一个使用Writer写的博客
今天开通的博客园的博客账户,先来尝试一下用哪种方式最适合写博. 目前用Live Writer. 以后计划在这里分享数据技术的技术体会和学习心得,尤其是大数据和数据仓库相关的知识.Hello my bl ...
- HTML5 javascript实现音乐播放器
准备毕业了,感觉好多东西都没学会,太多太多想学的知识,有种求知若渴的状态. 四年的大学就剩下一个多月了,无论将来多么困难,这条路是自己选的,走就要走的精彩! 自学了一点javascript.php,做 ...
- aix knowlgdgecenter
http://www-01.ibm.com/support/knowledgecenter/ssw_aix_53/com.ibm.aix.install/doc/insgdrf/HT_insgdrf_ ...
- C#,json字符串转换成Json对象
将JSON的请求参数转化为C#可序列化对象! JSON请求参数: "{\"id\":1,"name":"张三","dep ...
- [Regionals 2012 :: Asia - Tokyo ]
链接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=56 ...
- ChartControl第一课简短的控件初步设计
WinForms Controls >Controls > Chart Control > Getting Started This document gives you a qui ...