应无所住,而生其心
排名
1
文章
860
粉丝
112
评论
163
net core webapi post传递参数
庸人 : 确实坑哈,我也是下班好了好几次,发现后台传递对象是可以的,但...
百度编辑器自定义模板
庸人 : 我建议换个编辑器,因为现在百度富文本已经停止维护了,用tinymec...
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

领域驱动设计DDD ABP VNext 一:项目架构搭建,模块使用

5797人阅读 2022/5/10 22:25 总访问:5182565 评论:0 收藏:0 手机
分类: ABP

用户接口层改造

nuget中下载abp依赖

VoLo.Abp.AspNetCore.Mvc

ItemGroup添加方式

  1. <ItemGroup>
  2. <PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="4.4.4" />
  3. </ItemGroup>

我这里使用的是.net5.0的,最新版本是依赖与.net6.0的

添加模块类

添加一个模块类,继承AbpModule,依赖AbpAspNetCoreMvcModule模块

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using Volo.Abp.Modularity;
  6. using Volo.Abp.AspNetCore.Mvc;
  7. namespace WY.JBLand.API
  8. {
  9. [DependsOn(typeof(AbpAspNetCoreMvcModule))]
  10. public class WYJBLandAPIModule:AbpModule
  11. {
  12. }
  13. }

重写模块类中的ConfigureServices与OnApplicationInitialization方法,把Startup中的依赖注入与引用的中间件转移到这个模块中来。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using Volo.Abp.Modularity;
  6. using Volo.Abp.AspNetCore.Mvc;
  7. using Microsoft.Extensions.DependencyInjection;
  8. using Volo.Abp;
  9. using Microsoft.Extensions.Hosting;
  10. using Microsoft.AspNetCore.Builder;
  11. namespace WY.JBLand.API
  12. {
  13. [DependsOn(typeof(AbpAspNetCoreMvcModule))]
  14. public class WYJBLandAPIModule : AbpModule
  15. {
  16. /// <summary>
  17. /// 重写ConfigureServices转移Startup中依赖注入到这里
  18. /// </summary>
  19. /// <param name="context"></param>
  20. public override void ConfigureServices(ServiceConfigurationContext context)
  21. {
  22. var services = context.Services;
  23. services.AddControllers();
  24. base.ConfigureServices(context);
  25. }
  26. /// <summary>
  27. /// 重写OnApplicationInitialization转移Startup中引入的中间件到这里
  28. /// </summary>
  29. /// <param name="context"></param>
  30. public override void OnApplicationInitialization(ApplicationInitializationContext context)
  31. {
  32. var app = context.GetApplicationBuilder();
  33. var env = context.GetEnvironment();
  34. if (env.IsDevelopment())
  35. {
  36. app.UseDeveloperExceptionPage();
  37. }
  38. app.UseRouting();
  39. app.UseAuthorization();
  40. app.UseEndpoints(endpoints =>
  41. {
  42. endpoints.MapControllers();
  43. });
  44. base.OnApplicationInitialization(context);
  45. }
  46. }
  47. }

修改startup中的ConfigureServices与Configure方法,把原来代码删除掉添加如下代码即可。也就是直接加载我们刚刚添加的模块WYJBLandAPIModule,把这两个方法原来的工作给了WYJBLandAPIModule模块去做。

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddApplication<WYJBLandAPIModule>();
  4. }
  5. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  6. {
  7. app.InitializeApplication();
  8. }

基础设施层ORM之EntityFrameworkCore

添加相关依赖

连接的数据库根据需要选择,比如要连接的是sqlserver就添加Volo.Abp.EntityFrameworkCore.SqlServer

  1. <ItemGroup>
  2. <PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="4.4.4" />
  3. <PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="4.4.4" />
  4. <PackageReference Include="Volo.Abp.EntityFrameworkCore.SqlServer" Version="4.4.4" />
  5. </ItemGroup>
添加EF CORE的上下文对象类:

这里需要继承AbpDbContext,而不是直接的DbContext,ABP另外封装了一些内容。AbpDbContext本身也是继承了DbContext的。

  1. using Microsoft.EntityFrameworkCore;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using Volo.Abp.EntityFrameworkCore;
  8. using Volo.Abp.Data;
  9. namespace WY.JBLand.EntityFrameworkCore
  10. {
  11. [ConnectionStringName("conn_mssql")]
  12. public class WyJBLandDbContext : AbpDbContext<WyJBLandDbContext>
  13. {
  14. public WyJBLandDbContext(DbContextOptions<WyJBLandDbContext> options) : base(options)
  15. {
  16. }
  17. protected override void OnModelCreating(ModelBuilder modelBuilder)
  18. {
  19. base.OnModelCreating(modelBuilder);
  20. }
  21. }
  22. }
添加该层的模块类:

该层的注入这些就放到这里

  1. using System;
  2. using Volo.Abp.Modularity;
  3. using Volo.Abp.EntityFrameworkCore;
  4. using Microsoft.Extensions.DependencyInjection;
  5. namespace WY.JBLand.EntityFrameworkCore
  6. {
  7. [DependsOn(
  8. typeof(AbpEntityFrameworkCoreModule)
  9. )]
  10. public class EntityFrameworkCoreModule : AbpModule
  11. {
  12. public override void ConfigureServices(ServiceConfigurationContext context)
  13. {
  14. var services = context.Services;
  15. services.AddAbpDbContext<WyJBLandDbContext>();
  16. Configure<AbpDbContextOptions>(opt => {
  17. opt.UseSqlServer();
  18. });
  19. base.ConfigureServices(context);
  20. }
  21. }
  22. }
然后就可以在用户接口层中添加设施层模块,然后注入一个试试


如果能拿到注入就ok

创建领域层并通过EF CORE映射到数据库生成表

添加相关依赖

Volo.Abp.AspNetCore与Volo.Abp.Ddd.Domain

  1. <ItemGroup>
  2. <PackageReference Include="Volo.Abp.AspNetCore" Version="4.4.4" />
  3. <PackageReference Include="Volo.Abp.Ddd.Domain" Version="4.4.4" />
  4. </ItemGroup>

添加该层的模块类

到目前这里还用到像事件总线EventBus等待的一些东西,所以暂时什么都可以不注入,我们这小节把领域实体通过ef core映射到数据库生成表即可。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using Volo.Abp.Domain;
  7. using Volo.Abp.Modularity;
  8. namespace WY.JBLand.Domain
  9. {
  10. [DependsOn(
  11. typeof(AbpDddDomainModule)
  12. )]
  13. public class WYJBLandDomainModule : AbpModule
  14. {
  15. }
  16. }

创建一个简单的领域实体

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using Volo.Abp.Domain.Entities;
  7. namespace WY.JBLand.Domain.User
  8. {
  9. public class UserInfo:Entity<int>
  10. {
  11. public string UserName { get; set; }
  12. public string Password { get; set; }
  13. }
  14. }

给启动项目添加EF Code First迁移工具包

添加Tools库或者Design库都可以。Tools库里边其实就包含了Design库。
添加一个Microsoft.EntityFrameworkCore.Tools

  1. <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.12">

Tools库里边其实就包含了Design库,这里也能看到

工具包必须要添加不然你执行不了迁移命令的。

然后把领域层添加的实体加到基础设置层的EF CORE里边

最后执行EF CORE的迁移命令就可以根据实体生成好数据库了

1:Add-Migration InitialCreate
2:Update-Database

关于EF CORE 数据库迁移命令的详解,可以参考:
https://www.tnblog.net/aojiancc2/article/details/5370

应用层创建与AutoMapper使用

添加相关依赖

应用层目前需要添加的依赖有。添加依赖的时候都要注意版本,不然可能会有问题的


Volo.Abp.AspNetCore
Volo.Abp.AutoMapper
Volo.Abp.Ddd.Application

  1. <ItemGroup>
  2. <PackageReference Include="Volo.Abp.AspNetCore" Version="4.4.4" />
  3. <PackageReference Include="Volo.Abp.AutoMapper" Version="5.2.2" />
  4. <PackageReference Include="Volo.Abp.Ddd.Application" Version="4.4.4" />
  5. </ItemGroup>

添加好应用层模块类

到目前位置应用层模块类需要依赖的模块有


AbpDddApplicationModule
AbpAutoMapperModule
WyJBLandEntityFrameworkCoreModule

  1. using System;
  2. using Volo.Abp.Application;
  3. using Volo.Abp.AutoMapper;
  4. using Volo.Abp.Modularity;
  5. using WY.JBLand.EntityFrameworkCore;
  6. namespace WY.JBLand.Application
  7. {
  8. [DependsOn(
  9. typeof(AbpDddApplicationModule),
  10. typeof(AbpAutoMapperModule),
  11. typeof(WyJBLandEntityFrameworkCoreModule)
  12. )]
  13. public class WyJBLandApplicationModule : AbpModule
  14. {
  15. }
  16. }

添加一个DTO

就添加上面创建的userinfo实体对应的的DTO

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace WY.JBLand.Application.User
  7. {
  8. public class UserInfoDTO
  9. {
  10. public string UserName { get; set; }
  11. public string Password { get; set; }
  12. }
  13. }

大概的结构如下:

添加一个AutoMapper的Profile类用于设置对象与对象的映射关系

关于对象映射的官方文档:
https://docs.abp.io/zh-Hans/abp/4.4/Object-To-Object-Mapping

  1. using AutoMapper;
  2. using WY.JBLand.Application.User.Dto;
  3. using WY.JBLand.Domain.User;
  4. namespace WY.JBLand.Application
  5. {
  6. public class ApplicationAutoMapperProfile : Profile
  7. {
  8. public ApplicationAutoMapperProfile()
  9. {
  10. // 创建一个实体的映射
  11. CreateMap<UserInfo, UserInfoDTO>().ReverseMap();
  12. }
  13. }
  14. }

在应用层的模块注入ApplicationAutoMapperProfile

  1. using Volo.Abp.Application;
  2. using Volo.Abp.AutoMapper;
  3. using Volo.Abp.Modularity;
  4. using WY.JBLand.EntityFrameworkCore;
  5. namespace WY.JBLand.Application
  6. {
  7. [DependsOn(
  8. typeof(AbpDddApplicationModule),
  9. typeof(AbpAutoMapperModule),
  10. typeof(WyJBLandEntityFrameworkCoreModule)
  11. )]
  12. public class WyJBLandApplicationModule : AbpModule
  13. {
  14. public override void ConfigureServices(ServiceConfigurationContext context)
  15. {
  16. Configure<AbpAutoMapperOptions>(opt => {
  17. //添加一个具体映射配置模块
  18. opt.AddProfile<ApplicationAutoMapperProfile>();
  19. //添加该层所有映射配置模块
  20. //opt.AddMaps<WyJBLandApplicationModule>();
  21. });
  22. }
  23. }
  24. }

添加一个应用服务

应用服务接口

  1. using System.Collections.Generic;
  2. using Volo.Abp.Application.Services;
  3. using WY.JBLand.Application.User.Dto;
  4. namespace WY.JBLand.Application.User
  5. {
  6. public interface IUserInfoAppService : IApplicationService
  7. {
  8. List<UserInfoDTO> Get();
  9. }
  10. }

应用服务实现类。这里直接使用EF上下文对象测试还没有使用仓储

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using Volo.Abp.Application.Services;
  7. using Volo.Abp.Domain.Repositories;
  8. using WY.JBLand.Application.User.Dto;
  9. using WY.JBLand.Domain.User;
  10. using WY.JBLand.EntityFrameworkCore;
  11. namespace WY.JBLand.Application.User
  12. {
  13. public class UserInfoAppService : ApplicationService, IUserInfoAppService
  14. {
  15. private readonly WyJBLandDbContext _wyJBLandDbContext;
  16. public UserInfoAppService(WyJBLandDbContext wyJBLandDbContext)
  17. {
  18. _wyJBLandDbContext = wyJBLandDbContext;
  19. }
  20. public List<UserInfoDTO> Get()
  21. {
  22. List<UserInfo> userInfos = _wyJBLandDbContext.UserInfo.ToList();
  23. //使用AutoMapper进行对象转换
  24. var result = ObjectMapper.Map<List<UserInfo>, List<UserInfoDTO>>(userInfos);
  25. return result;
  26. }
  27. }
  28. }

大概的结构如下:

注意:用户接口层中要把依赖注入容易切换成AutoFac,不然你的AutoMapper,或者仓储这些的依赖拿到就会是空。因为abp vnext里边是使用AutoFac实现依赖注入的,而且不仅仅是引入改模块就行,还需要手动切换以下容器。是个坑要注意

然后在用户接口层使用以下这个应用服务即可

  1. [ApiController]
  2. [Route("[controller]")]
  3. public class WeatherForecastController : ControllerBase
  4. {
  5. private readonly ILogger<WeatherForecastController> _logger;
  6. private readonly IUserInfoAppService _userInfoAppService;
  7. public WeatherForecastController(ILogger<WeatherForecastController> logger, IUserInfoAppService userInfoAppService)
  8. {
  9. _logger = logger;
  10. _userInfoAppService = userInfoAppService;
  11. }
  12. [HttpGet("{id}")]
  13. public IEnumerable<UserInfoDTO> Get(int id)
  14. {
  15. List<UserInfoDTO> userInfos = _userInfoAppService.Get();
  16. return userInfos;
  17. }
  18. }

示例代码下载

https://download.tnblog.net/resource/index/0fc403f7505e48c99ed33f791c1d4ffa)


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)

评价

领域驱动设计DDD的点理解

有人误认为项目架构中加入xxRepository,xxDomain,xxValueObject就变成了DDD架构。如果没有悟出其精髓就在项目中加入这些...

领域驱动设计DDD之Repository

DDD中的Repository模式Repository模式也称存储库模式或仓储模式,根据Eric Evans的《领域驱动设计》一书,“存储库是一种封...

领域驱动设计DDD ABP VNext使用仓储

[TOC]领域驱动设计仓储介绍在领域层和数据映射层之间进行中介,使用类似集合的接口来操作领域对象.” (Martin Fowler)。 实...

领域驱动设计DDD ABP VNext领域模型 之 失血模型贫血模型充血模型胀血模型

[TOC]领域模型分为:失血模型,贫血模型,充血模型,胀血模型。 一、失血模型传统的三层架构,实体对象就是简单的POJO或者...

领域驱动设计概念的理解

[TOC]领域服务(Domain Service)领域中的一些概念不太适合建模为对象,即归类到实体对象或值对象,因为它们本质上就是一些...

Idea下使用maven搭建SSM()SpringMVC

Spring MVC是一款基于MVC架构模式的轻量级Web框架,其目的是将Web开发模块化,对整体架构进行解耦,简化Web开发流程。下面...

DIV+CSS网页布局常用的些基础知识整理

一.文件命名规范全局样式:global.css;框架布局:layout.css;字体样式:font.css;链接样式:link.css;打印样式:print...

如何使用图标像使用文字使用文本图标的方法

1.首先在Iconfont-阿里巴巴矢量图标库上面找到你需要的图标然后加入你的购物车然后选择图标;注意:每个类型的图标会大小不...

Python实例 2-12306抢票() 登陆

开坑年关将近,终于对12306下手了,,平安夜撸代码,攻克了12306的登陆 2018-12-24 22:16:00没错 这篇博客就写从零开始的异...

c使用unity实现依赖注入:依赖注入介绍

依赖注入的简单介绍直接关联是这样滴,耦合性超高的。这里有一个设计原则:依赖于抽象,而不是具体的实现试想一下如果做了...

c webservice基本使用

什么是webserviceWebservie是一种网络服务是一种与语言无关的服务webserver主要作用:1:可以跨平台跨语言访问2:可以做SOA...

c 根据数字把个集合拆分成多个子集合

有时间需要根据一个数子把一个集合拆分成多个子集合后在进行操作,就可以使用下面的代码。List&lt;List&lt;string&gt;&gt;l...

通过url传递个带井号()的参数并正确获取

正常情况下支持通过url是不能传递#等特殊符号的但是可以通过url编码解码解决通过url传递参数时某些特殊符号不能传递的问题n...

干货!div滚动到定位置就固定他。Vue中实现侧滚动到底部就固定

尊重原创:转载请注名出处div滚动到一定位置就固定他,例如左边的内容很多,右边的内容很少,如果不处理滚动到一定位置后右...

些有用的资源分享(工具+电子书)

工具类图片相关工具TinyPNG:https://tinypng.com/ 免费的在线图片压缩工具,压缩率高,无损画质,直接拖拽使用,很方便。p...