在正式进入主题之前我们来看下几个概念:
一、依赖倒置
依赖倒置是编程五大原则之一,即:
1、上层模块不应该依赖于下层模块,它们共同依赖于一个抽象。
2、抽象不能依赖于具体,具体依赖于抽象。
其中上层就是指使用者,下层就是指被使用者。
二、IoC控制反转
控制反转(IoC,全称Inversion of Control)是一种思想,所谓“控制反转”,就是反转获得依赖对象的过程。
三、依赖注入(DI)
依赖注入设计模式是一种在类及其依赖对象之间实现控制反转(IoC)思想的技术。
所谓依赖注入(DI,全称Dependency Injection),就是由IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。
依赖注入主要分为3种:构造函数注入、属性注入、方法注入。
这里就不做过多的描述,如果有机会会通过具体例子再和大家分享,下面我们正式进入本章主题。
PS:ASP.NET Core 内置的IoC容器目前只支持构造函数注入,以下我们也主要讲解构造函数注入的方式。
话不多说,直入主题看我们的解决方案结构:
分别对上面的工程进行简单的说明:
1、TianYa.DotNetShare.Model:为demo的实体层
2、TianYa.DotNetShare.Repository:为demo的仓储层即数据访问层
3、TianYa.DotNetShare.Service:为demo的服务层即业务逻辑层
4、TianYa.DotNetShare.CommTool:为demo的公共工具类库
5、TianYa.DotNetShare.SharpCore:为demo的Sharp核心类库
6、TianYa.DotNetShare.CoreMvcDemo:为demo的web层项目,MVC框架
约定:
1、公共的类库,我们选择.NET Standard 2.0作为目标框架,可与Framework进行共享。
2、本demo的web项目为ASP.NET Core Web 应用程序(.NET Core 2.2) MVC框架。
一、实体层
1、新建一个学生实体 Student
using System; using System.Collections.Generic; using System.Text; namespace TianYa.DotNetShare.Model { /// <summary> /// 学生类 /// </summary> public class Student { /// <summary> /// 学号 /// </summary> public string StuNo { get; set; } /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 年龄 /// </summary> public int Age { get; set; } /// <summary> /// 性别 /// </summary> public string Sex { get; set; } } }
demo中的实体就这样了
二、仓储层
本demo的仓储层需要引用我们的实体层TianYa.DotNetShare.Model
为什么选择用仓储,原因很简单,方便我们进行个性化扩展。在数据操作的底层进行其他个性化逻辑处理。
约定:
1、接口的定义放在根目录下,接口的实现类,统一放到Impl文件夹,表示实现类目录。
2、每个实体,对应一个仓储的接口和实现类,即有多少个实体,就对应创建多少个接口和实现类。
3、仓储层接口都以“I”开头,以“Repository”结尾。仓储层实现都以“Repository”结尾。
我们新建一个Student的仓储接口IStudentRepository.cs
using System; using System.Collections.Generic; using System.Text; using TianYa.DotNetShare.Model; namespace TianYa.DotNetShare.Repository { /// <summary> /// 学生类仓储层接口 /// </summary> public interface IStudentRepository { /// <summary> /// 根据学号获取学生信息 /// </summary> /// <param name="stuNo">学号</param> /// <returns>学生信息</returns> Student GetStuInfo(string stuNo); } }
接着在Impl中新建一个Student的仓储实现StudentRepository.cs
using System; using System.Collections.Generic; using System.Text; using TianYa.DotNetShare.Model; namespace TianYa.DotNetShare.Repository.Impl { /// <summary> /// 学生类仓储层 /// </summary> public class StudentRepository : IStudentRepository { /// <summary> /// 根据学号获取学生信息 /// </summary> /// <param name="stuNo">学号</param> /// <returns>学生信息</returns> public Student GetStuInfo(string stuNo) { //数据访问逻辑,此处为了演示就简单些 var student = new Student(); switch (stuNo) { case "10000": student = new Student() { StuNo = "10000", Name = "张三", Sex = "男", Age = 20 }; break; case "10001": student = new Student() { StuNo = "10001", Name = "钱七七", Sex = "女", Age = 18 }; break; case "10002": student = new Student() { StuNo = "10002", Name = "李四&q