添加EF上下文对象,添加接口、实现类以及无处不在的依赖注入(DI)

目录索引 

【无私分享:ASP.NET CORE 项目实战】目录索引

简介

  上一章,我们介绍了安装和新建控制器、视图,这一章我们来创建个数据模型,并且添加接口和实现类。

添加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)的更多相关文章

  1. 【无私分享:ASP.NET CORE 项目实战(第二章)】添加EF上下文对象,添加接口、实现类以及无处不在的依赖注入(DI)

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 上一章,我们介绍了安装和新建控制器.视图,这一章我们来创建个数据模型,并且添加接口和实现类. 添加EF上下文对象 按照我们以前 ...

  2. EF上下文对象线程内唯一性与优化

    在一次请求中,即一个线程内,若是用到EF数据上下文对象,就创建一个,这也加是很多人的代码中习惯在使用上下文对象时,习惯将对象建立在using中,也是为了尽早释放上下文对象, 但是如果有一个业务逻辑调用 ...

  3. EF上下文对象创建之线程内唯一

    在一次请求中,即一个线程内,若是用到EF数据上下文对象,就创建一个,那么会造成数据混乱,每次创建的对象执行相应的数据库操作,此同时,其他的EF对象内获得的数据可能已经是“过期”的了.即这个数据已经变动 ...

  4. 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, ...

  5. ThinkPHP6源码:从Http类的实例化看依赖注入是如何实现的

    ThinkPHP 6 从原先的 App 类中分离出 Http 类,负责应用的初始化和调度等功能,而 App 类则专注于容器的管理,符合单一职责原则. 以下源码分析,我们可以从 App,Http 类的实 ...

  6. 在.NET Core中处理一个接口多个不同实现的依赖注入问题

    前言 近段时间在准备公司的技术分享,所以这段时间将大部分时间放在准备分享内容上去了.博客也就停了一下下. 在.NET Core中处理依赖注入问题时,往往是定义好了一个操作规范的接口,会有N多个基于不同 ...

  7. 第四节:配置的读取、StartUp类、内置依赖注入和扩展改造

    一. 配置的读取 在Asp.Net Core中,有一个 appsettings.json 文件,用于存储相应的配置信息,读取的时,要通过构造函数注入:IConfiguration Configurat ...

  8. PHP类的反射和依赖注入

    /** * Class Point */ class Point { public $x; public $y; /** * Point constructor. * @param int $x ho ...

  9. Android开源项目发现--- 工具类依赖注入DI篇(持续更新)

    通过依赖注入减少View.服务.资源简化初始化,事件绑定等重复繁琐工作 1. AndroidAnnotations(Code Diet) android快速开发框架 项目地址:https://gith ...

随机推荐

  1. panel控件 换行

    Panel1.Controls.Add(new LiteralControl("<BR/>"));

  2. python基础之 Python os._exit() sys.exit() exit()区别

    Python退出程序的方式有两种:os._exit(), sys.exit() 1)os._exit() 直接退出 Python程序,其后的代码也不会继续执行. 2)sys.exit() 引发一个 S ...

  3. 关于 zend studio 中有些php 内置函数没有提示,或是有‘小黄色感叹号’

    解决办法: 1.修改项目 .buildpath 文件 <?xml version="1.0" encoding="UTF-8"?> <buil ...

  4. JFrame??

    swing的三个基本构造块:标签.按钮.文本字段.但需要个地方安放他们,并希望用户如何处理他们.JFrame类就是解决这个问题————它是一个容器,允许程序员把其他组件添加到它里面,把它们组织起来,并 ...

  5. spring中的定时任务调度用例

    在application-quartz.xml配置文件中添加如下配置信息: <!-- Quartz -->     <bean id="getSendEmailObject ...

  6. css3波浪形loading动画

    css3做个第一个动画,主要点在box-shadow和background的变化,虽然不难,但是还是有一定的技巧性的!备注下 html <div class="loading" ...

  7. python基础教程第2章——列表与元组笔记

    1.序列是Python中最基本的数据结构.序列中的每个元素被分配一个序列号——元素的位置,也称索引,第1个索引是0,第2为1,以此类推.序列中的最后1个元素为-1,倒数第2个位-2. python中有 ...

  8. 初学swift笔记运算符(二)

    swift 中的运算符 import Foundation //字符类型 var char: Character = "a" char="b" println( ...

  9. memcache 安装教程

    memcached:官网http://memcached.org/ 说明:memcached本身没有Linux版本,网上的windows 版本都是个人开发的. memcached和memcache区别 ...

  10. MATLAB介绍

    MATLAB MATLAB[1]  是美国MathWorks公司出品的商业数学软件,用于算法开发.数据可视化.数据分析以及数值计算的高级技术计算语言和交互式环境,主要包括MATLAB和Simulink ...