爆肝,重构框架,你懂得
This commit is contained in:
21
Yi.Framework.Net6/Yi.Framework.Service/Base/BaseService.cs
Normal file
21
Yi.Framework.Net6/Yi.Framework.Service/Base/BaseService.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Common.Attribute;
|
||||
using Yi.Framework.Interface.Base;
|
||||
using Yi.Framework.Repository;
|
||||
|
||||
namespace Yi.Framework.Service.Base
|
||||
{
|
||||
[AppService]
|
||||
public class BaseService<T> : IBaseService<T> where T : class, new()
|
||||
{
|
||||
public IRepository<T> _repository { get; set; }
|
||||
public BaseService(IRepository<T> iRepository)
|
||||
{
|
||||
_repository = iRepository;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
using AutoMapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Interface.Base.Crud;
|
||||
using Yi.Framework.Model.Base;
|
||||
using Yi.Framework.Repository;
|
||||
|
||||
namespace Yi.Framework.Service.Base.Crud
|
||||
{
|
||||
public abstract class AbstractKeyCrudAppService<TEntity, TEntityDto, TKey>
|
||||
: AbstractKeyCrudAppService<TEntity, TEntityDto, TKey, TEntityDto, TEntityDto>
|
||||
where TEntity : class, IEntity, new()
|
||||
{
|
||||
protected AbstractKeyCrudAppService(IRepository<TEntity> repository, IMapper mapper) : base(repository, mapper)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class AbstractKeyCrudAppService<TEntity, TEntityDto, TKey, TCreateUpdateInput>
|
||||
: AbstractKeyCrudAppService<TEntity, TEntityDto, TKey, TCreateUpdateInput, TCreateUpdateInput>
|
||||
where TEntity : class, IEntity, new()
|
||||
{
|
||||
protected AbstractKeyCrudAppService(IRepository<TEntity> repository, IMapper mapper) : base(repository, mapper)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class AbstractKeyCrudAppService<TEntity, TEntityDto, TKey, TCreateInput, TUpdateInput>
|
||||
: AbstractKeyCrudAppService<TEntity, TEntityDto, TEntityDto, TKey, TCreateInput, TUpdateInput>
|
||||
where TEntity : class, IEntity, new()
|
||||
{
|
||||
protected AbstractKeyCrudAppService(IRepository<TEntity> repository, IMapper mapper) : base(repository, mapper)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Task<TEntityDto> MapToGetListOutputDtoAsync(TEntity entity)
|
||||
{
|
||||
return MapToGetOutputDtoAsync(entity);
|
||||
}
|
||||
|
||||
protected override TEntityDto MapToGetListOutputDto(TEntity entity)
|
||||
{
|
||||
return MapToGetOutputDto(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class AbstractKeyCrudAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TCreateInput, TUpdateInput>
|
||||
: AbstractKeyReadOnlyAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey>,
|
||||
ICrudAppService<TGetOutputDto, TGetListOutputDto, TKey, TCreateInput, TUpdateInput>
|
||||
where TEntity : class, IEntity, new()
|
||||
{
|
||||
protected AbstractKeyCrudAppService(IRepository<TEntity> repository, IMapper mapper) : base(repository, mapper)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建
|
||||
/// </summary>
|
||||
/// <param name="dto"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<TGetOutputDto> CreateAsync(TCreateInput input)
|
||||
{
|
||||
|
||||
var entity = await MapToEntityAsync(input);
|
||||
|
||||
TryToSetTenantId(entity);
|
||||
|
||||
await Repository.InsertAsync(entity);
|
||||
|
||||
var entitydto = await MapToGetOutputDtoAsync(entity);
|
||||
return entitydto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除
|
||||
/// </summary>
|
||||
/// <param name="ids"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public virtual async Task DeleteAsync(IEnumerable<TKey> ids)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
protected abstract Task DeleteByIdAsync(TKey id);
|
||||
|
||||
/// <summary>
|
||||
/// 更新
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="dto"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<TGetOutputDto> UpdateAsync(TKey id, TUpdateInput input)
|
||||
{
|
||||
var entity = await GetEntityByIdAsync(id);
|
||||
|
||||
await UpdateValidAsync(entity, input);
|
||||
//TODO: Check if input has id different than given id and normalize if it's default value, throw ex otherwise
|
||||
await MapToEntityAsync(input, entity);
|
||||
await Repository.UpdateAsync(entity);
|
||||
|
||||
var entitydto = await MapToGetOutputDtoAsync(entity);
|
||||
return entitydto;
|
||||
}
|
||||
/// <summary>
|
||||
/// 效验更新
|
||||
/// </summary>
|
||||
/// <param name="idEntity"></param>
|
||||
/// <param name="dto"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual async Task UpdateValidAsync(TEntity idEntity, TUpdateInput dto)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将 更新输入dto转化为实体的异步
|
||||
/// </summary>
|
||||
/// <param name="updateInput"></param>
|
||||
/// <param name="entity"></param>
|
||||
protected virtual Task MapToEntityAsync(TUpdateInput updateInput, TEntity entity)
|
||||
{
|
||||
MapToEntity(updateInput, entity);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
/// <summary>
|
||||
/// 将 更新输入dto转化为实体的同步方法
|
||||
/// </summary>
|
||||
/// <param name="updateInput"></param>
|
||||
/// <param name="entity"></param>
|
||||
protected virtual void MapToEntity(TUpdateInput updateInput, TEntity entity)
|
||||
{
|
||||
ObjectMapper.Map(updateInput, entity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建dto 给 实体的转换的异步方法
|
||||
/// </summary>
|
||||
/// <param name="createInput"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Task<TEntity> MapToEntityAsync(TCreateInput createInput)
|
||||
{
|
||||
return Task.FromResult(MapToEntity(createInput));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建dto 给 实体的转换
|
||||
/// </summary>
|
||||
/// <param name="createInput"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual TEntity MapToEntity(TCreateInput createInput)
|
||||
{
|
||||
var entity = ObjectMapper.Map<TCreateInput, TEntity>(createInput);
|
||||
SetIdForGuids(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 给主键id赋值上guid
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
protected virtual void SetIdForGuids(TEntity entity)
|
||||
{
|
||||
if (entity is IEntity<Guid> entityWithGuidId && entityWithGuidId.Id == Guid.Empty)
|
||||
{
|
||||
//这里给主键赋值为guid,l临时写死属性名
|
||||
entity.GetType().GetProperty("Id").SetValue(entity, Guid.NewGuid());
|
||||
//EntityHelper.TrySetId(
|
||||
// entityWithGuidId,
|
||||
// () => GuidGenerator.Create(),
|
||||
// true
|
||||
//);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 给租户id赋值
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
protected virtual void TryToSetTenantId(TEntity entity)
|
||||
{
|
||||
//实现多租户接口
|
||||
//if (entity is IMultiTenant)
|
||||
//{
|
||||
// //给属性租户id赋值
|
||||
// if (ServiceLocator.GetTenantId(out var tid))
|
||||
// {
|
||||
// var tenantId = tid;
|
||||
|
||||
// var propertyInfo = entity.GetType().GetProperty(nameof(IMultiTenant.TenantId));
|
||||
|
||||
// if (propertyInfo == null || propertyInfo.GetSetMethod(true) == null)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// propertyInfo.SetValue(entity, tenantId);
|
||||
// }
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断租户id的属性是否为空
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual bool HasTenantIdProperty(TEntity entity)
|
||||
{
|
||||
return entity.GetType().GetProperty(nameof(IMultiTenant.TenantId)) != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
using AutoMapper;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Interface.Base.Crud;
|
||||
using Yi.Framework.Model.Base;
|
||||
using Yi.Framework.Repository;
|
||||
|
||||
namespace Yi.Framework.Service.Base.Crud
|
||||
{
|
||||
public abstract class AbstractKeyReadOnlyAppService<TEntity, TEntityDto, TKey>
|
||||
: AbstractKeyReadOnlyAppService<TEntity, TEntityDto, TEntityDto, TKey>
|
||||
where TEntity : class, IEntity, new()
|
||||
{
|
||||
protected AbstractKeyReadOnlyAppService(IRepository<TEntity> repository, IMapper mapper) : base(repository, mapper)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public abstract class AbstractKeyReadOnlyAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey> : ApplicationService,
|
||||
IReadOnlyAppService<TGetOutputDto, TGetListOutputDto, TKey>
|
||||
where TEntity : class, IEntity, new()
|
||||
{
|
||||
|
||||
public AbstractKeyReadOnlyAppService(IRepository<TEntity> repository, IMapper mapper) : base(mapper)
|
||||
{
|
||||
Repository = repository;
|
||||
|
||||
}
|
||||
protected IRepository<TEntity> Repository { get; set; }
|
||||
|
||||
|
||||
public async Task<TGetOutputDto> GetByIdAsync(TKey id)
|
||||
{
|
||||
var entity = await GetEntityByIdAsync(id);
|
||||
var entityDto = await MapToGetOutputDtoAsync(entity);
|
||||
|
||||
return entityDto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过id获取实体
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
protected abstract Task<TEntity> GetEntityByIdAsync(TKey id);
|
||||
/// <summary>
|
||||
/// 实体向Get输出映射的异步方法
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Task<TGetOutputDto> MapToGetOutputDtoAsync(TEntity entity)
|
||||
{
|
||||
return Task.FromResult(MapToGetOutputDto(entity));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实体向Get输出Dto映射的同步方法
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual TGetOutputDto MapToGetOutputDto(TEntity entity)
|
||||
{
|
||||
return ObjectMapper.Map<TEntity, TGetOutputDto>(entity);
|
||||
}
|
||||
/// <summary>
|
||||
/// 多个实体列表映射GetList输出dto列表的异步方法
|
||||
/// </summary>
|
||||
/// <param name="entities"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual async Task<List<TGetListOutputDto>> MapToGetListOutputDtosAsync(IEnumerable<TEntity> entities)
|
||||
{
|
||||
var dtos = new List<TGetListOutputDto>();
|
||||
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
dtos.Add(await MapToGetListOutputDtoAsync(entity));
|
||||
}
|
||||
|
||||
return dtos;
|
||||
}
|
||||
/// <summary>
|
||||
/// 实体列表映射GetList输出dto的异步方法
|
||||
/// </summary>
|
||||
/// <param name="entities"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Task<TGetListOutputDto> MapToGetListOutputDtoAsync(TEntity entity)
|
||||
{
|
||||
return Task.FromResult(MapToGetListOutputDto(entity));
|
||||
}
|
||||
/// <summary>
|
||||
/// 实体列表映射GetList输出dto的同步方法
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual TGetListOutputDto MapToGetListOutputDto(TEntity entity)
|
||||
{
|
||||
return ObjectMapper.Map<TEntity, TGetListOutputDto>(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using AutoMapper;
|
||||
using AutoMapper.Internal.Mappers;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Yi.Framework.Interface.Base.Crud;
|
||||
|
||||
namespace Yi.Framework.Service.Base.Crud
|
||||
{
|
||||
public class ApplicationService : IApplicationService
|
||||
{
|
||||
public ApplicationService(IMapper mapper)
|
||||
{
|
||||
ObjectMapper = mapper;
|
||||
}
|
||||
protected IMapper ObjectMapper { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using AutoMapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Common.Models;
|
||||
using Yi.Framework.Model.Base;
|
||||
using Yi.Framework.Repository;
|
||||
|
||||
namespace Yi.Framework.Service.Base.Crud
|
||||
{
|
||||
public abstract class CrudAppService<TEntity, TEntityDto, TKey>
|
||||
: CrudAppService<TEntity, TEntityDto, TKey, TEntityDto>
|
||||
where TEntity : class, IEntity<TKey>, new()
|
||||
{
|
||||
protected CrudAppService(IRepository<TEntity> repository, IMapper mapper) : base(repository, mapper)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class CrudAppService<TEntity, TEntityDto, TKey, TCreateInput>
|
||||
: CrudAppService<TEntity, TEntityDto, TKey, TCreateInput, TCreateInput>
|
||||
where TEntity : class, IEntity<TKey>, new()
|
||||
{
|
||||
protected CrudAppService(IRepository<TEntity> repository, IMapper mapper) : base(repository, mapper)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class CrudAppService<TEntity, TEntityDto, TKey, TCreateInput, TUpdateInput>
|
||||
: CrudAppService<TEntity, TEntityDto, TEntityDto, TKey, TCreateInput, TUpdateInput>
|
||||
where TEntity : class, IEntity<TKey>, new()
|
||||
{
|
||||
protected CrudAppService(IRepository<TEntity> repository, IMapper mapper) : base(repository, mapper)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Task<TEntityDto> MapToGetListOutputDtoAsync(TEntity entity)
|
||||
{
|
||||
return MapToGetOutputDtoAsync(entity);
|
||||
}
|
||||
|
||||
protected override TEntityDto MapToGetListOutputDto(TEntity entity)
|
||||
{
|
||||
return MapToGetOutputDto(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class CrudAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TCreateInput, TUpdateInput>
|
||||
: AbstractKeyCrudAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TCreateInput, TUpdateInput>
|
||||
where TEntity : class, IEntity<TKey>, new()
|
||||
{
|
||||
protected CrudAppService(IRepository<TEntity> repository, IMapper mapper) : base(repository, mapper)
|
||||
{
|
||||
}
|
||||
|
||||
protected override async Task DeleteByIdAsync(TKey id)
|
||||
{
|
||||
await DeleteAsync(new List<TKey> { id });
|
||||
}
|
||||
|
||||
protected override async Task<TEntity> GetEntityByIdAsync(TKey id)
|
||||
{
|
||||
return await Repository.GetByIdAsync(id);
|
||||
}
|
||||
|
||||
protected override void MapToEntity(TUpdateInput updateInput, TEntity entity)
|
||||
{
|
||||
if (updateInput is IEntityDto<TKey> entityDto)
|
||||
{
|
||||
entityDto.Id = entity.Id;
|
||||
}
|
||||
|
||||
base.MapToEntity(updateInput, entity);
|
||||
}
|
||||
|
||||
|
||||
public override async Task<Result<bool>> DeleteAsync(IEnumerable<TKey> ids)
|
||||
{
|
||||
await Repository.DeleteAsync(e => ids.Contains(e.Id));
|
||||
return Result<bool>.Success();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using AutoMapper;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Model.Base;
|
||||
using Yi.Framework.Repository;
|
||||
|
||||
namespace Yi.Framework.Service.Base.Crud
|
||||
{
|
||||
public abstract class ReadOnlyAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey>
|
||||
: AbstractKeyReadOnlyAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey>
|
||||
where TEntity : class, IEntity<TKey>, new()
|
||||
{
|
||||
protected ReadOnlyAppService(IRepository<TEntity> repository, IMapper mapper) : base(repository, mapper)
|
||||
{
|
||||
}
|
||||
|
||||
protected override async Task<TEntity> GetEntityByIdAsync(TKey id)
|
||||
{
|
||||
return await Repository.GetByIdAsync(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user