一、层次结构
*DDD 四层架构三层架构*1.应用层 (Application Layer):**高层代码、底层代码(BL)、Dto(合同层)
**2.领域层 (Domain Layer):**实体、常量、仓储接口
**3.基础设施层 /仓储层(Infrastructure Layer):**ORM、底层代码(仓储CRUD)
**4.用户表现层 (Presentation Layer):**前端交互
- 表现层 (Presentation Layer) : 前端界面。
- 业务逻辑层 (Business Logic Layer) : 后端逻辑。
- 数据访问层 (Data Access Layer):ORM框架处理数据。
四层架构实际上可以被视作:三层架构中业务逻辑层(BLL)进一步拆分的结果(应用层+领域层)
**【应用层】Application推荐写法 **
Student文件夹
└── Manage文件夹:StudentManagementService.cs //高层代码,Webapi控制器
└── Service文件夹:StudentService.cs //底层代码(BL)
一般来讲,底层代码分两个功能:
①BLL逻辑处理:实现和接口要分别写在应用层,应用合同层。
②CRUD处理:实现和接口要分别写在仓储层,领域层。
*** 底层代码要尽可能被高层代码复用,这样的底层代码才是有价值的 。高层代码通常不允许调用其余高层代码,因此高层代码很合适写简单逻辑。***
【应用合同层】Application.Contracts推荐写法
Student文件夹
├── Dto文件夹:各种Dto
└── Manage文件夹:IStudentManagementService.cs //高层代码,控制器(接口)
└── Service文件夹:IStudentService.cs //底层代码(接口)
二、ORM的使用
1.EFcore的配置步骤
①配置实体类长度和类型(bulder.Entity)
②配置上下文类(连接字符串,dbset)
③Webapi控制器注入使用
2.步骤一:配置实体类长度和类型
【EFcore/DbContextModelCreatingExtensions】
【仓储层】配置实体类(例如表的实体类字段类型、长度,确保映射成功)
public static class DbContextModelCreatingExtensions
{
public static void ConfigureCommon(this ModelBuilder builder)//扩展方法
{
builder.Entity<Student>(b => { b.ConfigureByConvention(); });//ConfigureByConvention方法配置了字段,实现方法略
}
}
具体的写法可以参考:
builder.Entity<Student>(b =>
{
// 配置 Id 字段
b.HasKey(s => s.Id); // 设置 Id 为主键
// 配置 Age 字段
b.Property(s => s.Age)
.IsRequired() // 设置 Age 字段为必填
.HasColumnName("Age") // 设置数据库列名
.HasColumnType("int"); // 设置数据库列的类型
// 配置 Name 字段
b.Property(s => s.Name)
.IsRequired() // 设置 Name 字段为必填
.HasMaxLength(100) // 设置最大长度为 100
.HasColumnName("Name") // 设置数据库列名
.HasColumnType("nvarchar(100)"); // 设置数据库列的类型
// 配置 Time 字段
b.Property(s => s.Time)
.IsRequired() // 设置 Time 字段为必填
.HasColumnName("Time") // 设置数据库列名
.HasColumnType("datetime"); // 设置数据库列的类型
// 其他配置
// 可以设置表名、索引、关系等
b.ToTable("Students"); // 设置表名为 Students
});
3.步骤二:配置上下文类
【EFcore/DbContext】
【仓储层】上下文类(连接字符串配置,确保找到该表)
[ConnectionStringName(“连接字符串”)]
public DbSet<Student> Student { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ConfigureCommon();//关联
}
4.步骤三:Webapi控制器注入使用
【Application】
【应用层】Webapi控制器调用
public class AService:
{
private readonly IRepository<Student, int> _Students;//私有可访问字段
public DATForeignStationDataAppService(IRepository<Student, int> Students)
{
_Students = Students;//注入仓储接口
}
}
//接口写法:
//var list = _Students.Where(x=>x.id==1).ToList();//使用仓储
四、AutoMapper的使用
【作用】可以用它处理实体映射
1.配置
【Application/AutoMapperProfile】
【应用层】配置映射方法
public class StudentProfiles : Profile
{
public StudentProfiles()
{
CreateMap<Student, StudentDto>(); //不需要配置List
}
}
2.使用
注意下面演示的list和entity两者是不一样的,是列表就用第一个,是实体就用第二个,配置映射方法时只需要配置实体即可(不需要配列表)
//调用示例
//1.添加映射模板
var config = new MapperConfiguration(cfg => cfg.AddProfile<XXXXXXXXAutoMapperProfile>());//XXXXXXXXAutoMapperProfile 配置CreateMap规则
//2.使用映射模板完成映射
var list = config.CreateMapper().Map<List<源类>, List<目标类>>(list); //list是源类的列表数据
var entity= config.CreateMapper().Map<源类,目标类>(en); //en是源类的实体数据
var studto = ObjectMapper.Map<Student, StudentDto>(entity);//调用示例
五、编写webapi控制器
【Application\Service】
【应用层】
注意的点:
1.这个Webapi控制器(ManagerService)必须继承base(否则扫不到该api)
2.可以通过EF的仓储获取数据表,也可以通过应用层的服务处理逻辑信息,请都使用依赖注入模式调用这些方法。
3.一个Webapi控制器不允许调用另一个Webapi控制器的方法,Webapi控制器是高层代码,写好后不应该轻易更改,因为可能前端调用了多次该接口。
版权归原作者 我是苏苏 所有, 如有侵权,请联系我们删除。