DDD 应用层完善

This commit is contained in:
橙子
2023-01-15 14:32:43 +08:00
parent 3bce7de015
commit f1e314fa13
60 changed files with 915 additions and 83 deletions

View File

@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>Yi.Framework.Application.Contracts</name>
</assembly>
<members>
<member name="T:Yi.Framework.Application.Contracts.Student.Dtos.StudentCreateInputVo">
<summary>
Student输入创建对象
</summary>
</member>
<member name="T:Yi.Framework.Application.Contracts.Student.IStudentService">
<summary>
服务抽象
</summary>
</member>
</members>
</doc>

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Application.Contracts.Student.Dtos
{
/// <summary>
/// Student输入创建对象
/// </summary>
public class StudentCreateInputVo
{
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Application.Contracts.Student.Dtos
{
public class StudentGetListInputVo
{
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Ddd.Dtos;
namespace Yi.Framework.Application.Contracts.Student.Dtos
{
public class StudentGetListOutputDto : IEntityDto<long>
{
public long Id { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Ddd.Dtos;
namespace Yi.Framework.Application.Contracts.Student.Dtos
{
public class StudentGetOutputDto : IEntityDto<long>
{
public long Id { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Application.Contracts.Student.Dtos
{
public class StudentUpdateInputVo
{
}
}

View File

@@ -3,13 +3,15 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Application.Contracts.Student.Dtos;
using Yi.Framework.Ddd.Services.Abstract;
namespace Yi.Framework.Application.Contracts.Student
{
/// <summary>
/// 服务抽象
/// </summary>
public interface IStudentService
public interface IStudentService : ICrudAppService<StudentGetOutputDto, StudentGetListOutputDto, long, StudentGetListInputVo, StudentCreateInputVo, StudentUpdateInputVo>
{
}

View File

@@ -4,14 +4,18 @@
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DocumentationFile>./ApplicationContractsSwaggerDoc.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Folder Include="Student\Dtos\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Framework.Domain.Shared\Yi.Framework.Domain.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="ApplicationContractsSwaggerDoc.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>Yi.Framework.Application</name>
</assembly>
<members>
<member name="T:Yi.Framework.Application.Student.StudentService">
<summary>
服务实现
</summary>
</member>
<member name="M:Yi.Framework.Application.Student.StudentService.PostShijie">
<summary>
你好世界
</summary>
<returns></returns>
</member>
</members>
</doc>

View File

@@ -9,17 +9,22 @@ using Yi.Framework.Domain.Student.IRepository;
using Microsoft.AspNetCore.Mvc;
using NET.AutoWebApi.Setting;
using Microsoft.AspNetCore.Http;
using Yi.Framework.Ddd.Services.Abstract;
using Yi.Framework.Application.Contracts.Student.Dtos;
using Yi.Framework.Domain.Student.Entities;
using Yi.Framework.Ddd.Services;
namespace Yi.Framework.Application.Student
{
/// <summary>
/// 服务实现
/// </summary>
public class StudentService : IStudentService, IAutoApiService
public class StudentService : CrudAppService<StudentEntity, StudentGetOutputDto, StudentGetListOutputDto, long, StudentGetListInputVo, StudentCreateInputVo, StudentUpdateInputVo>,
IStudentService, IAutoApiService
{
private readonly IStudentRepository _studentRepository;
private readonly StudentManager _studentManager;
public StudentService(IStudentRepository studentRepository, StudentManager studentManager )
public StudentService(IStudentRepository studentRepository, StudentManager studentManager)
{
_studentRepository = studentRepository;
_studentManager = studentManager;
@@ -27,11 +32,11 @@ namespace Yi.Framework.Application.Student
/// <summary>
/// 你好世界
/// </summary>
/// <param name="aaa"></param>
/// <returns></returns>
public string PostShijie(string aaa)
public async Task<List<StudentGetListOutputDto>> PostShijie()
{
return aaa;
var entities = await _studentRepository.GetMyListAsync();
return await MapToGetListOutputDtosAsync(entities);
}
}
}

View File

@@ -9,11 +9,10 @@
服务实现
</summary>
</member>
<member name="M:Yi.Framework.Application.Student.StudentService.PostShijie(System.String)">
<member name="M:Yi.Framework.Application.Student.StudentService.PostShijie">
<summary>
你好世界
</summary>
<param name="aaa"></param>
<returns></returns>
</member>
</members>

View File

@@ -5,7 +5,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DocumentationFile>./SwaggerDoc.xml</DocumentationFile>
<DocumentationFile>./ApplicationSwaggerDoc.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>

View File

@@ -26,9 +26,6 @@ namespace Microsoft.Extensions.DependencyInjection
c.SwaggerDoc("v1", apiInfo);
//添加注释服务
//为 Swagger JSON and UI设置xml文档注释路径
//获取应用程序所在目录(绝对路径不受工作目录影响建议采用此方法获取路径使用windwos&Linux
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
if (basePath is not null)
@@ -38,21 +35,7 @@ namespace Microsoft.Extensions.DependencyInjection
c.IncludeXmlComments(item, true);
}
}
//控制器层注释
//var entityXmlPath = Path.Combine(basePath, @"SwaggerDoc.xml");//实体注释
//c.IncludeXmlComments(apiXmlPath, true);//true表示显示控制器注释
//c.IncludeXmlComments(apiXmlPath, true);
//这里路径应该动态获取,先暂时写死
//c.IncludeXmlComments("E:\\Yi\\src\\Yi.Framework\\Yi.Framework.Application\\SwaggerDoc.xml", true);
//添加控制器注释
//c.DocumentFilter<SwaggerDocTag>();
//添加header验证信息
//c.OperationFilter<SwaggerHeader>();
//var security = new Dictionary<string, IEnumerable<string>> { { "Bearer", new string[] { } }, };
c.AddSecurityDefinition("JwtBearer", new OpenApiSecurityScheme()
{
Description = "直接输入Token即可",

View File

@@ -9,7 +9,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Cors" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
<PackageReference Include="NET.AutoApi" Version="1.0.4" />
<PackageReference Include="NET.AutoApi" Version="1.0.5" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>

View File

@@ -0,0 +1,36 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.Attributes;
using Yi.Framework.Core.Enums;
using Yi.Framework.Core.Helper;
using Yi.Framework.Ddd.Dtos;
using Yi.Framework.Ddd.Repositories;
namespace Yi.Framework.Core.Sqlsugar.Repositories
{
[AppService(ServiceType = typeof(IRepository<>))]
public class SqlsugarRepository<T> : SimpleClient<T>, IRepository<T> where T : class, new()
{
public SqlsugarRepository(ISqlSugarClient context) : base(context)
{
}
protected ISugarQueryable<T> _DbQueryable { get { return base.AsQueryable(); } set { } }
protected ISqlSugarClient _Db { get { return Context; } set { } }
public async Task<List<T>> GetPageListAsync(Expression<Func<T, bool>> whereExpression, IPagedAndSortedResultRequestDto page)
{
return await base.GetPageListAsync(whereExpression, new PageModel { PageIndex = page.PageIndex, PageSize = page.PageSize });
}
public async Task<List<T>> GetPageListAsync(Expression<Func<T, bool>> whereExpression, IPagedAndSortedResultRequestDto page, Expression<Func<T, object>>? orderByExpression = null, OrderByEnum orderByType = OrderByEnum.Asc)
{
return await base.GetPageListAsync(whereExpression, new PageModel { PageIndex = page.PageIndex, PageSize = page.PageSize }, orderByExpression, orderByType.EnumToEnum<OrderByType>());
}
}
}

View File

@@ -1,23 +0,0 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.Attribute;
using Yi.Framework.Ddd.Repositories;
namespace Yi.Framework.Core.Sqlsugar.Repository
{
[AppService(ServiceType =typeof(IRepository<>))]
public class SqlsugarRepository<T> : SimpleClient<T>, IRepository<T> where T : class, new()
{
public SqlsugarRepository(ISqlSugarClient context) : base(context)
{
}
protected ISugarQueryable<T> _DbQueryable { get { return base.Context.Queryable<T>(); } set { } }
protected ISqlSugarClient _Db { get { return base.Context; } set { } }
}
}

View File

@@ -4,7 +4,7 @@ using StartupModules;
using Yi.Framework.Core.Configuration;
using Yi.Framework.Core.Options;
using Yi.Framework.Core.Sqlsugar.Extensions;
using Yi.Framework.Core.Sqlsugar.Repository;
using Yi.Framework.Core.Sqlsugar.Repositories;
using Yi.Framework.Ddd;
using Yi.Framework.Ddd.Repositories;

View File

@@ -4,13 +4,13 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Core.Attribute
namespace Yi.Framework.Core.Attributes
{
/// 1、[AppService]:自动去找接口,如果存在就是接口,如果不存在就是本身
/// 2、[AppService(ServiceType = typeof(注册抽象或者接口或者本身))]手动去注册放type即可
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class AppServiceAttribute : System.Attribute
public class AppServiceAttribute : Attribute
{
/// <summary>
/// 服务声明周期

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Core.Enums
{
public enum OrderByEnum
{
Asc,
Desc
}
}

View File

@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Core.Enum
namespace Yi.Framework.Core.Enums
{
public enum ResultCodeEnum
{

View File

@@ -5,7 +5,7 @@ using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.Enum;
using Yi.Framework.Core.Enums;
namespace Yi.Framework.Core.Exceptions
{

View File

@@ -1,7 +1,7 @@
using System;
using System.Runtime.ExceptionServices;
using Microsoft.Extensions.Logging;
using Yi.Framework.Core.Enum;
using Yi.Framework.Core.Enums;
namespace Yi.Framework.Core.Exceptions;

View File

@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.Enum;
using Yi.Framework.Core.Enums;
namespace Yi.Framework.Core.Exceptions
{

View File

@@ -5,7 +5,7 @@ using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.Enum;
using Yi.Framework.Core.Enums;
namespace Yi.Framework.Core.Exceptions
{

View File

@@ -5,7 +5,7 @@ using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.Attribute;
using Yi.Framework.Core.Attributes;
using Yi.Framework.Core.DependencyInjection;
namespace Yi.Framework.Core.Extensions

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Core.Helper
{
public static class EnumHelper
{
public static New EnumToEnum<New>(this object oldEnum)
{
if (oldEnum is null)
{
throw new ArgumentNullException(nameof(oldEnum));
}
return (New)Enum.ToObject(typeof(New), oldEnum.GetHashCode());
}
}
}

View File

@@ -4,7 +4,7 @@ using System.IO;
using System.Linq;
using System.Text;
namespace Yi.Framework.Common.Helper
namespace Yi.Framework.Core.Helper
{
public class FileHelper : IDisposable
{
@@ -128,7 +128,7 @@ namespace Yi.Framework.Common.Helper
FileStream f = File.Create(Path);
f.Close();
}
StreamWriter f2 = new StreamWriter(Path, false, System.Text.Encoding.GetEncoding("gb2312"));
StreamWriter f2 = new StreamWriter(Path, false, Encoding.GetEncoding("gb2312"));
f2.Write(Strings);
f2.Close();
f2.Dispose();
@@ -175,7 +175,7 @@ namespace Yi.Framework.Common.Helper
s = "不存在相应的目录";
else
{
StreamReader f2 = new StreamReader(Path, System.Text.Encoding.GetEncoding("gb2312"));
StreamReader f2 = new StreamReader(Path, Encoding.GetEncoding("gb2312"));
s = f2.ReadToEnd();
f2.Close();
f2.Dispose();

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Dtos
{
public interface IHasTotalCount
{
long Total { get; set; }
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Dtos
{
public interface IListResult<T>
{
IReadOnlyList<T> Items { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Dtos.Abstract
{
public interface IPagedAllResultRequestDto
{
DateTime? StartTime { get; set; }
DateTime? EndTime { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Dtos
{
public interface IPagedAndSortedResultRequestDto
{
int PageIndex { get; set; }
int PageSize { get; set; }
string? PageSort { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Dtos
{
public interface IPagedResult<T> : IListResult<T>, IHasTotalCount
{
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Dtos
{
[Serializable]
public class ListResultDto<T> : IListResult<T>
{
public IReadOnlyList<T> Items
{
get { return _items ?? (_items = new List<T>()); }
set { _items = value; }
}
private IReadOnlyList<T> _items;
public ListResultDto()
{
}
public ListResultDto(IReadOnlyList<T> items)
{
Items = items;
}
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Dtos
{
public class PagedAllResultRequestDto: PagedAndSortedResultRequestDto
{
public DateTime? StartTime { get; set; }
public DateTime? EndTime { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Dtos
{
public class PagedAndSortedResultRequestDto : IPagedAndSortedResultRequestDto
{
public int PageIndex { get; set; }
public int PageSize { get; set; }
public string? PageSort { get; set; }
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Dtos
{
public class PagedResultDto<T>:ListResultDto<T>, IPagedResult<T>
{
public long Total { get; set; }
public PagedResultDto()
{
}
public PagedResultDto(long totalCount, IReadOnlyList<T> items)
: base(items)
{
Total = totalCount;
}
}
}

View File

@@ -11,13 +11,13 @@ namespace Yi.Framework.Ddd.Entities
//
// 摘要:
// Returns an array of ordered keys for this entity.
object[] GetKeys();
}
public interface IEntity<TKey> : IEntity
{
//
// 摘要:
// Unique identifier for this entity.
TKey Id { get; }
TKey Id { get;}
}
}

View File

@@ -1,13 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.Enums;
using Yi.Framework.Ddd.Dtos;
namespace Yi.Framework.Ddd.Repositories
{
public interface IRepository<T>
{
//单查
Task<T> GetByIdAsync(dynamic id);
Task<T> GetSingleAsync(Expression<Func<T, bool>> whereExpression);
Task<T> GetFirstAsync(Expression<Func<T, bool>> whereExpression);
Task<bool> IsAnyAsync(Expression<Func<T, bool>> whereExpression);
Task<int> CountAsync(Expression<Func<T, bool>> whereExpression);
//多查
Task<List<T>> GetListAsync();
Task<List<T>> GetListAsync(Expression<Func<T, bool>> whereExpression);
//分页查
Task<List<T>> GetPageListAsync(Expression<Func<T, bool>> whereExpression, IPagedAndSortedResultRequestDto page);
Task<List<T>> GetPageListAsync(Expression<Func<T, bool>> whereExpression, IPagedAndSortedResultRequestDto page, Expression<Func<T, object>>? orderByExpression = null, OrderByEnum orderByType = OrderByEnum.Asc);
//插入
Task<bool> InsertAsync(T insertObj);
Task<bool> InsertOrUpdateAsync(T data);
Task<bool> InsertOrUpdateAsync(List<T> datas);
Task<int> InsertReturnIdentityAsync(T insertObj);
Task<long> InsertReturnBigIdentityAsync(T insertObj);
Task<long> InsertReturnSnowflakeIdAsync(T insertObj);
Task<T> InsertReturnEntityAsync(T insertObj);
Task<bool> InsertRangeAsync(List<T> insertObjs);
//更新
Task<bool> UpdateAsync(T updateObj);
Task<bool> UpdateRangeAsync(List<T> updateObjs);
Task<bool> UpdateAsync(Expression<Func<T, T>> columns, Expression<Func<T, bool>> whereExpression);
//删除
Task<bool> DeleteAsync(T deleteObj);
Task<bool> DeleteAsync(List<T> deleteObjs);
Task<bool> DeleteAsync(Expression<Func<T, bool>> whereExpression);
Task<bool> DeleteByIdAsync(dynamic id);
Task<bool> DeleteByIdsAsync(dynamic[] ids);
}
}

View File

@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Services
namespace Yi.Framework.Ddd.Services.Abstract
{
public interface IApplicationService
{

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Services.Abstract
{
public interface ICreateAppService<TEntityDto>
: ICreateAppService<TEntityDto, TEntityDto>
{
}
public interface ICreateAppService<TGetOutputDto, in TCreateInput>
: IApplicationService
{
Task<TGetOutputDto> CreateAsync(TCreateInput input);
}
}

View File

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Services.Abstract
{
public interface ICreateUpdateAppService<TEntityDto, in TKey>
: ICreateUpdateAppService<TEntityDto, TKey, TEntityDto, TEntityDto>
{
}
public interface ICreateUpdateAppService<TEntityDto, in TKey, in TCreateUpdateInput>
: ICreateUpdateAppService<TEntityDto, TKey, TCreateUpdateInput, TCreateUpdateInput>
{
}
public interface ICreateUpdateAppService<TGetOutputDto, in TKey, in TCreateUpdateInput, in TUpdateInput>
: ICreateAppService<TGetOutputDto, TCreateUpdateInput>,
IUpdateAppService<TGetOutputDto, TKey, TUpdateInput>
{
}
}

View File

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Ddd.Dtos;
namespace Yi.Framework.Ddd.Services.Abstract
{
public interface ICrudAppService<TEntityDto, in TKey>
: ICrudAppService<TEntityDto, TKey, PagedAndSortedResultRequestDto>
{
}
public interface ICrudAppService<TEntityDto, in TKey, in TGetListInput>
: ICrudAppService<TEntityDto, TKey, TGetListInput, TEntityDto>
{
}
public interface ICrudAppService<TEntityDto, in TKey, in TGetListInput, in TCreateInput>
: ICrudAppService<TEntityDto, TKey, TGetListInput, TCreateInput, TCreateInput>
{
}
public interface ICrudAppService<TEntityDto, in TKey, in TGetListInput, in TCreateInput, in TUpdateInput>
: ICrudAppService<TEntityDto, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
{
}
public interface ICrudAppService<TGetOutputDto, TGetListOutputDto, in TKey, in TGetListInput, in TCreateInput, in TUpdateInput>
: IReadOnlyAppService<TGetOutputDto, TGetListOutputDto, TKey, TGetListInput>,
ICreateUpdateAppService<TGetOutputDto, TKey, TCreateInput, TUpdateInput>,
IDeleteAppService<TKey>
{
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Services.Abstract
{
public interface IDeleteAppService<in TKey> : IApplicationService
{
Task DeleteAsync(TKey id);
}
}

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Ddd.Dtos;
using Yi.Framework.Ddd.Entities;
namespace Yi.Framework.Ddd.Services.Abstract
{
public interface IReadOnlyAppService<TEntityDto, in TKey>
: IReadOnlyAppService<TEntityDto, TEntityDto, TKey, PagedAndSortedResultRequestDto>
{
}
public interface IReadOnlyAppService<TEntityDto, in TKey, in TGetListInput>
: IReadOnlyAppService<TEntityDto, TEntityDto, TKey, TGetListInput>
{
}
public interface IReadOnlyAppService<TGetOutputDto, TGetListOutputDto, in TKey, in TGetListInput>
: IApplicationService
{
Task<TGetOutputDto> GetAsync(TKey id);
Task<PagedResultDto<TGetListOutputDto>> GetListAsync(TGetListInput input);
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Services.Abstract
{
public interface IUpdateAppService<TEntityDto, in TKey>
: IUpdateAppService<TEntityDto, TKey, TEntityDto>
{
}
public interface IUpdateAppService<TGetOutputDto, in TKey, in TUpdateInput>
: IApplicationService
{
Task<TGetOutputDto> UpdateAsync(TKey id, TUpdateInput input);
}
}

View File

@@ -1,4 +1,5 @@
using System;
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -7,6 +8,7 @@ using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Services
{
public abstract class ApplicationService
{
{
public IMapper _mapper { get; set; }
}
}

View File

@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Ddd.Dtos;
using Yi.Framework.Ddd.Entities;
using Yi.Framework.Ddd.Services.Abstract;
namespace Yi.Framework.Ddd.Services
{
public abstract class CrudAppService<TEntity, TEntityDto, TKey>
: CrudAppService<TEntity, TEntityDto, TKey, PagedAndSortedResultRequestDto>
where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey>
{
}
public abstract class CrudAppService<TEntity, TEntityDto, TKey, TGetListInput>
: CrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TEntityDto>
where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey>
{
}
public abstract class CrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput>
: CrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TCreateInput>
where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey>
{
}
public abstract class CrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
: CrudAppService<TEntity, TEntityDto, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey>
{
protected override Task<TEntityDto> MapToGetListOutputDtoAsync(TEntity entity)
{
return MapToGetOutputDtoAsync(entity);
}
}
public abstract class CrudAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
: ReadOnlyAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput>,
ICrudAppService<TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
where TEntity : class, IEntity<TKey>
where TGetOutputDto : IEntityDto<TKey>
where TGetListOutputDto : IEntityDto<TKey>
{
protected virtual Task<TEntity> MapToEntityAsync(TCreateInput createInput)
{
var entity = _mapper.Map<TEntity>(createInput);
//这里判断实体的T给id赋值
//雪花id
//if (entity is IEntity<long>)
//{
// //使用反射暂时先使用sqlsuga的雪花id提供
// entityWithLongId.Id = SqlSugar.SnowFlakeSingle.Instance.NextId();
//}
return Task.FromResult(entity);
}
protected virtual Task MapToEntityAsync(TUpdateInput updateInput, TEntity entity)
{
_mapper.Map(updateInput, entity);
return Task.CompletedTask;
}
/// <summary>
/// 增
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<TGetOutputDto> CreateAsync(TCreateInput input)
{
var entity = await MapToEntityAsync(input);
await _repository.InsertAsync(entity);
return await MapToGetOutputDtoAsync(entity);
}
/// <summary>
/// 删
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public async Task DeleteAsync(TKey id)
{
if (id is null)
{
throw new ArgumentNullException(nameof(id));
}
await _repository.DeleteByIdAsync(id);
}
/// <summary>
/// 改
/// </summary>
/// <param name="id"></param>
/// <param name="input"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public virtual async Task<TGetOutputDto> UpdateAsync(TKey id, TUpdateInput input)
{
if (id is null)
{
throw new ArgumentNullException(nameof(id));
}
var entity = await _repository.GetByIdAsync(id);
await MapToEntityAsync(input, entity);
await _repository.UpdateAsync(entity);
return await MapToGetOutputDtoAsync(entity);
}
}
}

View File

@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Ddd.Dtos;
using Yi.Framework.Ddd.Entities;
using Yi.Framework.Ddd.Repositories;
using Yi.Framework.Ddd.Services.Abstract;
namespace Yi.Framework.Ddd.Services
{
public abstract class ReadOnlyAppService<TEntity, TEntityDto, TKey>
: ReadOnlyAppService<TEntity, TEntityDto, TEntityDto, TKey, PagedAndSortedResultRequestDto>
where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey>
{
}
public abstract class ReadOnlyAppService<TEntity, TEntityDto, TKey, TGetListInput>
: ReadOnlyAppService<TEntity, TEntityDto, TEntityDto, TKey, TGetListInput>
where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey>
{
}
public abstract class ReadOnlyAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput> : ApplicationService,
IReadOnlyAppService<TGetOutputDto, TGetListOutputDto, TKey, TGetListInput>
where TEntity : class, IEntity
{
protected IRepository<TEntity> _repository { get; }
//Mapper
protected virtual Task<TGetOutputDto> MapToGetOutputDtoAsync(TEntity entity)
{
return Task.FromResult(_mapper.Map<TEntity, TGetOutputDto>(entity));
}
protected virtual Task<List<TGetListOutputDto>> MapToGetListOutputDtosAsync(List<TEntity> entities)
{
var dtos = _mapper.Map<List<TGetListOutputDto>>(entities);
return Task.FromResult(dtos);
}
protected virtual Task<TGetListOutputDto> MapToGetListOutputDtoAsync(TEntity entity)
{
var dto = _mapper.Map<TEntity, TGetListOutputDto>(entity);
return Task.FromResult(dto);
}
/// <summary>
/// 单查
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public async Task<TGetOutputDto> GetAsync(TKey id)
{
if (id is null)
{
throw new ArgumentNullException(nameof(id));
}
var entity = await _repository.GetByIdAsync(id);
return await MapToGetOutputDtoAsync(entity);
}
/// <summary>
/// 全查
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<PagedResultDto<TGetListOutputDto>> GetListAsync(TGetListInput input)
{
var totalCount = await _repository.CountAsync(_ => true);
var entities = new List<TEntity>();
var entityDtos = new List<TGetListOutputDto>();
if (totalCount > 0)
{
if (input is IPagedAndSortedResultRequestDto sortInput)
{
entities = await _repository.GetPageListAsync(_ => true, sortInput);
}
//这里还可以追加如果是审计日志,继续拼接条件即可
else
{
entities = await _repository.GetListAsync();
}
entityDtos = await MapToGetListOutputDtosAsync(entities);
}
return new PagedResultDto<TGetListOutputDto>(
totalCount,
entityDtos
);
}
}
}

View File

@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DocumentationFile>./SwaggerDoc.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Framework.Core.AutoMapper\Yi.Framework.Core.AutoMapper.csproj" />
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
</ItemGroup>
</Project>

View File

@@ -4,10 +4,19 @@
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DocumentationFile>./YiFrameworkSwaggerDoc.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Framework.Core.AutoMapper\Yi.Framework.Core.AutoMapper.csproj" />
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="YiFrameworkSwaggerDoc.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>Yi.Framework.Ddd</name>
</assembly>
<members>
<member name="M:Yi.Framework.Ddd.Services.CrudAppService`7.CreateAsync(`5)">
<summary>
</summary>
<param name="input"></param>
<returns></returns>
</member>
<member name="M:Yi.Framework.Ddd.Services.CrudAppService`7.DeleteAsync(`3)">
<summary>
</summary>
<param name="id"></param>
<returns></returns>
<exception cref="T:System.ArgumentNullException"></exception>
</member>
<member name="M:Yi.Framework.Ddd.Services.CrudAppService`7.UpdateAsync(`3,`6)">
<summary>
</summary>
<param name="id"></param>
<param name="input"></param>
<returns></returns>
<exception cref="T:System.ArgumentNullException"></exception>
</member>
<member name="M:Yi.Framework.Ddd.Services.ReadOnlyAppService`5.GetAsync(`3)">
<summary>
单查
</summary>
<param name="id"></param>
<returns></returns>
<exception cref="T:System.ArgumentNullException"></exception>
</member>
<member name="M:Yi.Framework.Ddd.Services.ReadOnlyAppService`5.GetListAsync(`4)">
<summary>
全查
</summary>
<param name="input"></param>
<returns></returns>
</member>
</members>
</doc>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>Yi.Framework.Domain</name>
</assembly>
<members>
<member name="T:Yi.Framework.Domain.Student.Entities.StudentEntity">
<summary>
学生实体
</summary>
</member>
<member name="P:Yi.Framework.Domain.Student.Entities.StudentEntity.Name">
<summary>
学生名称
</summary>
</member>
<member name="T:Yi.Framework.Domain.Student.IRepository.IStudentRepository">
<summary>
仓储抽象
</summary>
</member>
<member name="T:Yi.Framework.Domain.Student.StudentManager">
<summary>
领域服务
</summary>
</member>
</members>
</doc>

View File

@@ -4,16 +4,21 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Ddd.Entities;
namespace Yi.Framework.Domain.Student.Entities
{
/// <summary>
/// 实体
/// 学生实体
/// </summary>
[SugarTable("Student")]
public class StudentEntity
public class StudentEntity : IEntity<long>
{
public long Id { get; set; }
/// <summary>
/// 学生名称
/// </summary>
public string Name { get; set; } = string.Empty;
}
}

View File

@@ -13,5 +13,6 @@ namespace Yi.Framework.Domain.Student.IRepository
/// </summary>
public interface IStudentRepository:IRepository<StudentEntity>
{
Task<List<StudentEntity>> GetMyListAsync();
}
}

View File

@@ -4,10 +4,18 @@
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DocumentationFile>./DomainSwaggerDoc.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Framework.Domain.Shared\Yi.Framework.Domain.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="DomainSwaggerDoc.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -4,8 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.Sqlsugar.Repository;
using Yi.Framework.Ddd.Repository;
using Yi.Framework.Core.Sqlsugar.Repositories;
using Yi.Framework.Domain.Student.Entities;
using Yi.Framework.Domain.Student.IRepository;
@@ -14,10 +13,15 @@ namespace Yi.Framework.Sqlsugar.Student
/// <summary>
/// 仓储实现方式
/// </summary>
public class StudentRepository : SqlsugarRepository<StudentEntity> ,IStudentRepository
public class StudentRepository : SqlsugarRepository<StudentEntity>, IStudentRepository
{
public StudentRepository(ISqlSugarClient context) : base(context)
{
}
public async Task<List<StudentEntity>> GetMyListAsync()
{
return await _DbQueryable.ToListAsync();
}
}
}

View File

@@ -8,9 +8,7 @@ using Yi.Framework.Core;
using Yi.Framework.Core.AutoMapper;
using Yi.Framework.Core.Extensions;
using Yi.Framework.Core.Sqlsugar;
using Yi.Framework.Core.Sqlsugar.Repository;
using Yi.Framework.Ddd;
using Yi.Framework.Ddd.Repository;
using Yi.Framework.Domain;
using Yi.Framework.Domain.Shared;
using Yi.Framework.Sqlsugar;
@@ -41,8 +39,5 @@ builder.UseYiModules(
builder.Host.UseAutoFacServerProviderFactory();
var app = builder.Build();
//ʹ<>ö<EFBFBD>̬api
app.UseAutoApiService();
app.MapControllers();
app.Run();

View File

@@ -1,5 +1,4 @@
using Yi.Framework.Core.Attribute;
using Yi.Framework.Core.DependencyInjection;
using Yi.Framework.Core.DependencyInjection;
namespace Yi.Framework.Web
{