从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之六 || API项目整体搭建 6.1 仓储模式
本文3.0版本文章
本文涉及的内容,同样适用于3.0版本,不用修改。
前言
书接上文:前几回文章中,我们花了三天的时间简单了解了下接口文档Swagger框架,已经完全解放了我们的以前的Word说明文档,并且可以在线进行调试,而且当项目开始之中,我们可以定义一些空的接口,或者可以返回假数据,这样真正达到了前后端不等待的缺陷,还是很不错的,当然,这离我说的前后端分离还是相差甚远,今天呢,我们就简单搭建下我们的项目架构。
本项目是我自己的一个真实项目,数据都是真实的,之前搭建过一个MVC + EF Code First的项目,本项目就是基于这个了,前一段时间我已经搭建起来了,是这样的,本系列教程会重新开始。
零、完成图中的粉色部分
先简单解释下各层之间的调用关系:
除了项目对外暴露的是 Api 展示层,和核心的实体 Model 层外,
仓储模块(作为一个数据库管理员,直接操作数据库,实体模型):
BaseRepository(基类仓储) 继承实现了 接口IBaseRepository,这里放公共的方法,
AdvertisementRepostitory 继承 BaseRepository<Advertisement>, IAdvertisementRepositoryService模块(处理业务逻辑,可以直接使用ViewModel视图模型):
BaseService 调用 BaseRepository,同时继承 IBaseService
AdvertisementServices 继承 BaseServices<Advertisement>, IAdvertisementServices
2019-08-30:关于仓储的相关话题
很多人都有一个这样的想法,仓储就是Dal层?我这里简单说一下两者的区别(我Blog.Core项目可能不是体现的出来,DDD可能更好理解):
1、仓储是一种模式,可以单建一层,也可以放到基础设施层,
而Dal是三层架构种的某一层,是一个架构
2、仓储官方的定义,他是一个管理者,去管理实体对象和ORM映射对象的一个集合,是ORM操作db,
而Dal就是完完全全的操作db数据库了,
请注意,不要把 Sqlsugar 当成三层中的 sqlhelper,不一样!
3、仓储更多的是一个聚合,在下一个系列DDD中,我们说到了一个概念,一个聚合的划分其实就是一个仓储。
4、然后我们进一步细化,一个仓储 = 一个聚合 = 有一个聚合根 = 一个微服务!
多个微服务之间交互,就是通过聚合根来的。
一、创建实体Model数据层
其中,Models文件夹中,存放的是整个项目的数据库表实体类,这里是手动创建的,当然也可以自动创建,在以后的文章中我会提到,用到的是SqlSugar的T4创建,这里先埋一个伏笔。
提示:这个伏笔已经完成,地址《三十二║ 四种方法快速实现项目的半自动化搭建》
然后,VeiwModels文件夹,是存放的DTO实体类,在开发中,一般接口需要接收数据,返回数据,我之前都是这么红果果的使用的,后来发现弊端很大,不仅把重要信息暴露出去(比如手机号等),还对数据造成冗余(比如我需要接收用户的生日,还需要具体的年、月、日这就是三个字段,当然您也可以手动拆开,这只是一个栗子,所以不能直接用数据库实体类接收),就用到了DTO类的转换,但是频繁的转换又会麻烦,别慌,以后的文章中,我们会引用AutoMapper来自动转换,这里再买一个伏笔。
提示:这个伏笔已经完成,地址《十三 || DTOs 对象映射使用》
最后的是MessageModel和TableModel,大家也基本一看就能明白,因为在前端接口中,需要固定的格式,以及操作,不能把数据直接发出去,会报错,在以后的Vue开发中,会提到这个,这里又买了一个伏笔。 如下:
/// <summary>
/// 通用返回信息类
/// </summary>
public class MessageModel<T>
{
/// <summary>
/// 操作是否成功
/// </summary>
public bool Success { get; set; }
/// <summary>
/// 返回信息
/// </summary>
public string Msg { get; set; }
/// <summary>
/// 返回数据集合
/// </summary>
public List<T> Data { get; set; } }
整个项目运行,没错,继续创建下一层。
二、设计仓储接口与其实现类
创建Blog.Core.IRepository和 Blog.Core.Repository 仓储层:
这里简单说下仓储层:repository就是一个管理数据持久层的,它负责数据的CRUD(Create, Read, Update, Delete) service layer是业务逻辑层,它常常需要访问repository层。有网友这么说:Repository(仓储):协调领域和数据映射层,利用类似与集合的接口来访问领域对象。Repository 是一个独立的层,介于领域层与数据映射层(数据访问层)之间。它的存在让领域层感觉不到数据访问层的存在,它提供一个类似集合的接口提供给领域层进行领域对象的访问。Repository 是仓库管理员,领域层需要什么东西只需告诉仓库管理员,由仓库管理员把东西拿给它,并不需要知道东西实际放在哪。
我们定义了IRepository层,提供了所有的操作接口,今天搭建框架,我简单地写一个实例,明天我们将把所有的方法嵌套进去。
在 IAdvertisementRepository.cs 中,添加一个求和接口
public interface IAdvertisementRepository
{
int Sum(int i, int j);
}
然后再在 AdvertisementRepository.cs 中去实现该接口,记得要添加引用,这个应该都会,就不细说了。
public class AdvertisementRepository : IAdvertisementRepository
{
public int Sum(int i, int j)
{
return i + j;
}
}
运行项目,一起正常,继续往下。
三、设计服务接口与其实现类
创建 Blog.Core.IServices 和 Blog.Core.Services 业务逻辑层,就是和我们平时使用的三层架构中的BLL层很相似:
Service层只负责将Repository仓储层的数据进行调用,至于如何是与数据库交互的,它不去管,这样就可以达到一定程度上的解耦,假如以后数据库要换,比如MySql,那Service层就完全不需要修改即可,至于真正意义的解耦,还是得靠依赖注入,这下一节我们会讲到。
这里在 IAdvertisementServices 中添加接口
namespace Blog.Core.IServices
{
public interface IAdvertisementServices
{
int Sum(int i, int j);
}
}
然后再在 AdvertisementServices 中去实现该接口
public class AdvertisementServices : IAdvertisementServices
{
IAdvertisementRepository dal = new AdvertisementRepository(); public int Sum(int i, int j)
{
return dal.Sum(i, j); }
}
注意!这里是引入了三个命名空间
using Blog.Core.IRepository;
using Blog.Core.IServices;using Blog.Core.Repository;
四、创建 Controller 接口调用
将系统默认的ValueController删除,手动添加一个BlogController控制器,可以选择一个空的,也可以选择一个带有默认读写实例的。如下:
[Produces("application/json")]
[Route("api/Blog")]
[Authorize(Policy ="Admin")]
public class BlogController : Controller
{
// GET: api/Blog
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
} // GET: api/Blog/5
[HttpGet("{id}", Name = "Get")]
public string Get(int id)
{
return "value";
} // POST: api/Blog
[HttpPost]
public void Post([FromBody]string value)
{
} // PUT: api/Blog/5
[HttpPut("{id}")]
public void Put(int id, [FromBody]string value)
{
} // DELETE: api/ApiWithActions/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
接下来,在应用层添加服务层的引用
using Blog.Core.IServices;
using Blog.Core.Services;
然后,改写Get方法
·······// GET: api/Blog
/// <summary>
/// Sum接口
/// </summary>
/// <param name="i">参数i</param>
/// <param name="j">参数j</param>
/// <returns></returns>
[HttpGet]
public int Get(int i,int j)
{
IAdvertisementServices advertisementServices = new AdvertisementServices();
return advertisementServices.Sum(i,j);
}
F5 运行项目,调试如下:
天呀!出错辣!别慌,还记得昨天咱们加的权限么,嗯!就是那里,手动模拟登陆,获取Token,注入,不会的可以看上一篇,然后再执行,结果:
五、结语
好啦,今天的工作暂时到这里了,你可以看到整体项目的搭建,结构,如何引用,如何测试等,当然,这里还是有很多小问题,比如:
·如果每个仓储都需要这么写,至少是四遍,会不会太麻烦;
·每次Controller接口调用,需要引入很多命名空间
·等等等等
这些问题,下一节我们都会带大家一起去慢慢解决!
六、Github && Gitee
https://github.com/anjoy8/Blog.Core.git
https://gitee.com/laozhangIsPhi/Blog.Core
从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之六 || API项目整体搭建 6.1 仓储模式的更多相关文章
- Z从壹开始前后端分离【 .NET Core2.2/3.0 +Vue2.0 】框架之六 || API项目整体搭建 6.1 仓储+服务+抽象接口模式
本文梯子 本文3.0版本文章 前言 零.完成图中的粉色部分 2019-08-30:关于仓储的相关话题 一.创建实体Model数据层 二.设计仓储接口与其实现类 三.设计服务接口与其实现类 四.创建 C ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之七 || API项目整体搭建 6.2 轻量级ORM
更新 1.在使用的时候,特别是更新数据的时候,如果不知道哪里有问题,可以查看数据库 和 实体类 的字段,是否大小写一致,比如 name 和 Name 2.在使用Sqlsugar 的 CodeFirst ...
- Z从壹开始前后端分离【 .NET Core2.2/3.0 +Vue2.0 】框架之七 || API项目整体搭建 6.2 轻量级ORM
本文梯子 本文3.0版本文章 前言 零.今天完成的蓝色部分 0.创建实体模型与数据库 1.实体模型 2.创建数据库 一.在 IRepository 层设计接口 二.在 Repository 层实现相应 ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之八 || API项目整体搭建 6.3 异步泛型仓储+依赖注入初探
代码已上传Github+Gitee,文末有地址 番外:在上文中,也是遇到了大家见仁见智的评论和反对,嗯~说实话,积极性稍微受到了一丢丢的打击,不过还好,还是有很多很多很多人的赞同的,所以会一直坚持下去 ...
- Z从壹开始前后端分离【 .NET Core2.2/3.0 +Vue2.0 】框架之八 || API项目整体搭建 6.3 异步泛型仓储+依赖注入初探
本文梯子 本文3.0版本文章 回顾 1.Sqlsugar 的使用 2.修改数据连接字符串 今天要完成的浅紫色部分 一.设计仓储基类接口——IBaseRepository.cs 二.将其他的仓储接口,继 ...
- k.tt 研究下生成的逻辑代码:从壹开始前后端分离 [.netCore 填坑 ] 三十二║ 四种方法快速实现项目的半自动化搭建
更新 1.更新小伙伴 @大龄Giser 提出好点子:试试VS的插件扩展:VSIX.ItemProject等,将T4模板给制作插件,这里先记下,有懂的小伙伴可以自己先试试,我会在以后更新. 2.感谢小伙 ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存
代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十一 || AOP自定义筛选,Redis入门 11.1
代码已上传Github+Gitee,文末有地址 书说上文<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之十 || AOP面向切面编程浅 ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十二 || 三种跨域方式比较,DTOs(数据传输对象)初探
更新反馈 1.博友@落幕残情童鞋说到了,Nginx反向代理实现跨域,因为我目前还没有使用到,给忽略了,这次记录下,为下次补充.此坑已填 2.提示:跨域的姊妹篇——<三十三║ ⅖ 种方法实现完美跨 ...
随机推荐
- 使用java检测网络连接状况
windows中可以通过在cmd中使用ping命令来检测网络连接状况,如下: 网络连接正常时: 网络未连接时: 在java中可以通过调用ping命令来判断网络是否连接正常: package modul ...
- 安卓---RedioButton(单选按钮)、CheckBox(复选按钮)
<RadioGroup android:layout_width="fill_parent" android:layout_height="wrap_content ...
- Go的context的问题
Go的context的问题 2017-05-29 最近被由context引发的一个bug坑得不轻,所以反思一下Go的context的问题. context是隐式的约束,没有检测 如果我们写一个函数,比 ...
- C++11中list特有版本的算法
与其他的容器不一样,链表类型的list和forward_list定义了几个成员函数形式的算法,这些函数和前面的所总结的通用算法不同,对于list来说,最好使用自己的特有算法,下面介绍一下主要的几个算法 ...
- Redis详解(一)------ redis的简介与安装
工作中一直在用 Redis,但是一直没有进行系统的总结,这个系列的博客将整体的介绍 Redis 的用法. 1.Redis 的简介 Redis:REmote DIctionary Server(远程字典 ...
- 《HelloGitHub》第 26 期
公告 五月初 hellogithub.com 网站做了优化和试错.因为我个人能力原因,导致这段时间网站出现了间断性不能访问,现在问题已经修复.多谢大家的支持.理解和反馈. 本期新增了"星图& ...
- django+mysql的使用
Django中每一个模型model都对应于数据库中的一张表,每个模型中的字段都对应于数据库表的列.方便的是,django可以自动生成这些create table, alter table, drop ...
- 百度病了,必应挂了,Yandex疯了。
前天一篇<搜索引擎百度已死>的文章火遍了互联网圈.文中作者指出如今的百度搜索首页一大半都是百度自家的产品,比如你搜索特普朗,你会发现第一页的结果分别是:百度百科.贴吧.百家号.百家号.百家 ...
- 【Python3爬虫】常见反爬虫措施及解决办法(二)
这一篇博客,还是接着说那些常见的反爬虫措施以及我们的解决办法.同样的,如果对你有帮助的话,麻烦点一下推荐啦. 一.防盗链 这次我遇到的防盗链,除了前面说的Referer防盗链,还有Cookie防盗链和 ...
- 设计模式-发布订阅模式(javaScript)
1. 前言 2. 什么是发布订阅模式 3. 发布订阅优缺点 4. 举例 4. 总结 1. 前言 发布订阅者模式是为了发布者和订阅者之间避免产生依赖关系,发布订阅者之间的订阅关系由一个中介列表来维护.发 ...