【无私分享:ASP.NET CORE 项目实战(第二章)】添加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\Startup.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 现在很火热,但是网上的很多资料都是前篇一律的复制,所以有很多问题我也暂时没有解决,希望大家能共同帮助一下!

时间: 2024-09-27 16:41:40

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

【无私分享:ASP.NET CORE 项目实战(第四章)】Code First 创建数据库和数据表

目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 本章我们来介绍下Asp.net Core 使用 CodeFirst 创建数据库和表,通过 控制台 和 dotnet ef 两种方式 修改EF上下文对象,添加测试类 我修改了一下名字,Domains 改为了 wkmvc.Data 我们新建一个文件夹 Models 用于存放 模型类 我们在Models下面再新建一个文件夹SysModelsMange 用于区域模型类 我们新建一个测试类SYS_USER namespace wkm

【无私分享:ASP.NET CORE 项目实战(第五章)】Repository仓储 UnitofWork

目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 本章我们来创建仓储类Repository 并且引入 UnitOfWork 我对UnitOfWork的一些理解  UnitOfWork 工作单元,对于这个的解释和实例,网上很多很多大神之作,我在这就不班门弄斧了,只是浅谈 一下个人理解,不一定对,希望大家指正: UnitOfWork 看了很多,个人理解就是 统一事务,在很多操作中我们可能是进行多项操作的,比如 同时保存两个表的数据,如果我们先保存一个表(SaveChanges

【无私分享:ASP.NET CORE 项目实战(第六章)】读取配置文件(一) appsettings.json

目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 在我们之前的Asp.net mvc 开发中,一提到配置文件,我们不由的想到 web.config 和 app.config,在 core 中,我们看到了很多的变化,新的配置系统显得更加轻量级,具有更好的扩展性,并且支持多样化的数据源. 博客园对于这个的讲解很多,比如:Artche ,但是,没有点基础看老A的博客还是有些吃力的,对于老A介绍的配置,我也是看的一头雾水,在后面的文章中,我会用像我们这些菜鸟容易接受的方式,重新解

【无私分享:ASP.NET CORE 项目实战(第五章)】Code First 创建数据库和数据表

目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 本章我们来介绍下Asp.net Core 使用 CodeFirst 创建数据库和表 修改EF上下文对象,添加测试类 我修改了一下名字,Domains 改为了 wkmvc.Data 我们新建一个文件夹 Models 用于存放 模型类 我们在Models下面再新建一个文件夹SysModelsMange 用于区域模型类 我们新建一个测试类SYS_USER namespace wkmvc.Data.Models  { public

【无私分享:ASP.NET CORE 项目实战(第九章)】创建区域Areas,添加TagHelper

目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 在Asp.net Core VS2015中,我们发现还有很多不太简便的地方,比如右击添加视图,转到试图页等功能图不见了,虽然我们可以通过工具栏的自定义命令,把这两个右击菜单添加上,但是貌似是灰色的不能用. 其实,这样也好,通过手动创建,更让我们深刻的理解MVC以及路由之间的关系,很多人认为底层的东西是高大上的,比如一提到汇编,很多人感觉牛的不行不行的,其实术业有专攻,做程序的感觉搞核电的很牛,搞核电的同样也感觉做程序的很牛

【无私分享:ASP.NET CORE 项目实战(第八章)】读取配置文件(二) 读取自定义配置文件

目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 我们在 读取配置文件(一) appsettings.json 中介绍了,如何读取appsettings.json. 但随之产生了问题:我们使用的是在 Startup.cs 中(如下图)来实现配置读取,有两个问题 ① 我们如果定义N种配置,是否要再这里添加N条这样的配置 : ② 如果我们的配置不想写在appsettings.json中呢 解决问题 带着上面的两个问题,我们首先来添加一个配置文件 siteconfig.json

【无私分享:ASP.NET CORE 项目实战(第三章)】EntityFramework下领域驱动设计的应用

目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 在我们 [无私分享:从入门到精通ASP.NET MVC] 系列中,我们其实也是有DDD思想的,但是没有完全的去实现,因为并不是所有的好的东西都必须要用到的,还是根据实际情况,DDD在大型的系统中是非常好的一种设计思想,这点不否认.但是根据具体情况而言,在我们小型的项目中,我们设计框架的更多考虑的是让使用者快速.便捷的开发,能快速的了解框架进行项目开发. 重构我们的思路 最近研究了一下几位大神的博客,特别是:@腾飞(Jess

【无私分享:ASP.NET CORE 项目实战(第十一章)】Asp.net Core 缓存 MemoryCache 和 Redis

目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 经过 N 久反复的尝试,翻阅了网上无数的资料,GitHub上下载了十几个源码参考, Memory 和 Redis 终于写出一个 简陋 的 封装,为了统一和易用,我们两种缓存都统一实现了一个接口 ICacheService,微软也有很多是通过IDistributedCache,大家可以参考 https://docs.asp.net/en/latest/performance/caching/distributed.html 

【无私分享:ASP.NET CORE 项目实战(第七章)】文件操作 FileHelper

目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 在程序设计中,我们很多情况下,会用到对文件的操作,在 上一个系列 中,我们有很多文件基本操作的示例,在Core中有一些改变,主要是我们常用的Server.MapPath()不存在了,不知道后续的版本会不会有,在这里,我们只能自己封装方法去实现.今天,我们就对一些基本的操作写了一个 FileHelper 类,供大家探讨.在此要感谢以为不愿意透漏姓名的大神的帮助:@YINYEJUN 获取文件的绝对路径  在以前的操作中,这个应