我可以在表示层中使用领域层实体的类型吗?
Can I use type of domain layer entities in presentation layer?
表示层在我的应用层调用一个方法(CreateEvent)。此方法使用通用参数:
public async Task<string> CreateEvent<T, TDocument>(T @event)
where T : class
where TDocument : Document
{
using (var scope = _serviceProvider.CreateScope())
{
var myRepository = scope.ServiceProvider.GetRequiredService<ICarrierEventRepository<TDocument>>();
var eventMapped = _mapper.Map<TDocument>(@event);
await myRepository.InsertOneAsync(eventMapped);
return eventMapped.Id.ToString();
}
}
参数 T 是表示层中的对象定义,TDocument 是我的实体(领域层)继承的抽象 class。
public abstract class Document : IDocument
{
public ObjectId Id { get ; set ; }
//some other properties....
}
实体示例:
public class PaackCollection : Document
{
public string ExternalId { get; set; }
public DateTime At { get; set; }
//some other properties....
}
在表示层,我这样调用我的 CreateEvent 方法:
[HttpPost]
public async Task<IActionResult> Post(PayLoadPaackModel payLoadPaackModel)
{
var idCreated = await _carrierEventService.CreateEvent<PayLoadPaackModel, Domain.Entities.MongoDb.PaackCollection>(payLoadPaackModel);
//some code here....
return Ok("OK");
}
可以使用 Domain.Entities.MongoDb.PaackCollection 的类型作为参数,知道它属于域层吗?通常表示层只与应用层通信。
谢谢指教
更新
此解决方案有效:
调用创建事件:
await _carrierEventService.CreateEvent(paackEventMapped);
public async Task<string> CreateEvent<T>(T @event)
where T : class
{
using (var scope = _serviceProvider.CreateScope())
{
Type typeParameterType = typeof(T);
if (typeParameterType.Equals(typeof(PaackEventDto)))
{
var eventMapped = _mapper.Map<PaackEvent>(@event);
var carrierEventRepository = scope.ServiceProvider.GetRequiredService<ICarrierEventRepository<PaackEvent>>();
await carrierEventRepository.InsertOneAsync(eventMapped);
return eventMapped.Id.ToString();
}
else if (typeParameterType.Equals(typeof(LaPosteEventDto)))
{
var eventMapped = _mapper.Map<LaposteEvent>(@event);
var carrierEventRepository = scope.ServiceProvider.GetRequiredService<ICarrierEventRepository<LaposteEvent>>();
await carrierEventRepository.InsertOneAsync(eventMapped);
return eventMapped.Id.ToString();
}
else
return default;
}
}
是否有另一种解决方案使用泛型来避免有很多条件来比较对象?因为我可以有 50 个不同的对象...
更新
我找到了获取映射器 DestinationType 的解决方案:
var destinationMap = _mapper.ConfigurationProvider.GetAllTypeMaps().First(t => t.SourceType == typeParameterType);
var destType = destinationMap.DestinationType;
var eventMapped = _mapper.Map(@event, typeParameterType, destType);
它正在工作,现在如何使用 destType 获取 carrierEventRepository 的类型?
我尝试这个 var repository = typeof(ICarrierEventRepository<>).MakeGenericType(destType);
但我可以使用我的存储库的方法...
这是另一个示例,我将 Dto 传递到我的 Api 基础 class。
public async Task<ServiceResponse<TServiceResponce>> CreateAsyncServiceWrapper<TServiceResponce, TModelToCreate>(string url, TModelToCreate ModelToCreate)
{ Removed Code}
我是这样称呼它的
_serviceResponce = await _compRepo.CreateAsyncServiceWrapper<ServiceResponse<CompanyDto>, CreateCompanyDto>(StaticDetails.CompanyAPIPath, model);
这是我的一个博客中的示例。
/// <summary>
/// Create a new company Record.
/// </summary>
/// <param name="createCompanyDto"></param>
/// <returns></returns>
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(CompanyDto))]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<CompanyDto>> CreateCompany([FromBody] CreateCompanyDto createCompanyDto)
{
if (createCompanyDto == null)
{
return BadRequest(ModelState);
}
if (!ModelState.IsValid) { return BadRequest(ModelState); }
var _newCompany = await _companyService.AddCompanyAsync(createCompanyDto);
if (_newCompany.Success == false && _newCompany.Message == "Exist")
{
return Ok(_newCompany);
}
if (_newCompany.Success == false && _newCompany.Message == "RepoError")
{
ModelState.AddModelError("", $"Some thing went wrong in respository layer when adding company {createCompanyDto}");
return StatusCode(500, ModelState);
}
if (_newCompany.Success == false && _newCompany.Message == "Error")
{
ModelState.AddModelError("", $"Some thing went wrong in service layer when adding company {createCompanyDto}");
return StatusCode(500, ModelState);
}
//Return new company created
return CreatedAtRoute("GetCompanyByGUID", new { CompanyGUID = _newCompany.Data.GUID }, _newCompany);
}
我终于找到了解决方案:
要使用 Automapper 获取目标类型,我使用 _mapper.ConfigurationProvider.GetAllTypeMaps()
,MakeGenericType
帮助我设置 ICarrierEventRepository<T>
并使用此 帮助我使用动态关键字调用方法 InsertOneAsync
.
public async Task<string> CreateEvent<T>(T @event)
where T : class
{
using (var scope = _serviceProvider.CreateScope())
{
//Get destination type
Type typeParameterType = typeof(T);
var destinationMap = _mapper.ConfigurationProvider.GetAllTypeMaps().First(t => t.SourceType == typeParameterType);
var destType = destinationMap.DestinationType;
//Map with destination type
var eventMapped = _mapper.Map(@event, typeParameterType, destType);
//Get repository register in services
var repository = typeof(ICarrierEventRepository<>).MakeGenericType(destType);
dynamic repo = scope.ServiceProvider.GetRequiredService(repository);
//Insert on database
await repo.InsertOneAsync((dynamic)eventMapped);
//Get generate id
return ((dynamic)eventMapped).Id.ToString();
}
}
表示层在我的应用层调用一个方法(CreateEvent)。此方法使用通用参数:
public async Task<string> CreateEvent<T, TDocument>(T @event)
where T : class
where TDocument : Document
{
using (var scope = _serviceProvider.CreateScope())
{
var myRepository = scope.ServiceProvider.GetRequiredService<ICarrierEventRepository<TDocument>>();
var eventMapped = _mapper.Map<TDocument>(@event);
await myRepository.InsertOneAsync(eventMapped);
return eventMapped.Id.ToString();
}
}
参数 T 是表示层中的对象定义,TDocument 是我的实体(领域层)继承的抽象 class。
public abstract class Document : IDocument
{
public ObjectId Id { get ; set ; }
//some other properties....
}
实体示例:
public class PaackCollection : Document
{
public string ExternalId { get; set; }
public DateTime At { get; set; }
//some other properties....
}
在表示层,我这样调用我的 CreateEvent 方法:
[HttpPost]
public async Task<IActionResult> Post(PayLoadPaackModel payLoadPaackModel)
{
var idCreated = await _carrierEventService.CreateEvent<PayLoadPaackModel, Domain.Entities.MongoDb.PaackCollection>(payLoadPaackModel);
//some code here....
return Ok("OK");
}
可以使用 Domain.Entities.MongoDb.PaackCollection 的类型作为参数,知道它属于域层吗?通常表示层只与应用层通信。
谢谢指教
更新 此解决方案有效:
调用创建事件:
await _carrierEventService.CreateEvent(paackEventMapped);
public async Task<string> CreateEvent<T>(T @event)
where T : class
{
using (var scope = _serviceProvider.CreateScope())
{
Type typeParameterType = typeof(T);
if (typeParameterType.Equals(typeof(PaackEventDto)))
{
var eventMapped = _mapper.Map<PaackEvent>(@event);
var carrierEventRepository = scope.ServiceProvider.GetRequiredService<ICarrierEventRepository<PaackEvent>>();
await carrierEventRepository.InsertOneAsync(eventMapped);
return eventMapped.Id.ToString();
}
else if (typeParameterType.Equals(typeof(LaPosteEventDto)))
{
var eventMapped = _mapper.Map<LaposteEvent>(@event);
var carrierEventRepository = scope.ServiceProvider.GetRequiredService<ICarrierEventRepository<LaposteEvent>>();
await carrierEventRepository.InsertOneAsync(eventMapped);
return eventMapped.Id.ToString();
}
else
return default;
}
}
是否有另一种解决方案使用泛型来避免有很多条件来比较对象?因为我可以有 50 个不同的对象...
更新
我找到了获取映射器 DestinationType 的解决方案:
var destinationMap = _mapper.ConfigurationProvider.GetAllTypeMaps().First(t => t.SourceType == typeParameterType);
var destType = destinationMap.DestinationType;
var eventMapped = _mapper.Map(@event, typeParameterType, destType);
它正在工作,现在如何使用 destType 获取 carrierEventRepository 的类型?
我尝试这个 var repository = typeof(ICarrierEventRepository<>).MakeGenericType(destType);
但我可以使用我的存储库的方法...
这是另一个示例,我将 Dto 传递到我的 Api 基础 class。
public async Task<ServiceResponse<TServiceResponce>> CreateAsyncServiceWrapper<TServiceResponce, TModelToCreate>(string url, TModelToCreate ModelToCreate)
{ Removed Code}
我是这样称呼它的
_serviceResponce = await _compRepo.CreateAsyncServiceWrapper<ServiceResponse<CompanyDto>, CreateCompanyDto>(StaticDetails.CompanyAPIPath, model);
这是我的一个博客中的示例。
/// <summary>
/// Create a new company Record.
/// </summary>
/// <param name="createCompanyDto"></param>
/// <returns></returns>
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(CompanyDto))]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<CompanyDto>> CreateCompany([FromBody] CreateCompanyDto createCompanyDto)
{
if (createCompanyDto == null)
{
return BadRequest(ModelState);
}
if (!ModelState.IsValid) { return BadRequest(ModelState); }
var _newCompany = await _companyService.AddCompanyAsync(createCompanyDto);
if (_newCompany.Success == false && _newCompany.Message == "Exist")
{
return Ok(_newCompany);
}
if (_newCompany.Success == false && _newCompany.Message == "RepoError")
{
ModelState.AddModelError("", $"Some thing went wrong in respository layer when adding company {createCompanyDto}");
return StatusCode(500, ModelState);
}
if (_newCompany.Success == false && _newCompany.Message == "Error")
{
ModelState.AddModelError("", $"Some thing went wrong in service layer when adding company {createCompanyDto}");
return StatusCode(500, ModelState);
}
//Return new company created
return CreatedAtRoute("GetCompanyByGUID", new { CompanyGUID = _newCompany.Data.GUID }, _newCompany);
}
我终于找到了解决方案:
要使用 Automapper 获取目标类型,我使用 _mapper.ConfigurationProvider.GetAllTypeMaps()
,MakeGenericType
帮助我设置 ICarrierEventRepository<T>
并使用此 InsertOneAsync
.
public async Task<string> CreateEvent<T>(T @event)
where T : class
{
using (var scope = _serviceProvider.CreateScope())
{
//Get destination type
Type typeParameterType = typeof(T);
var destinationMap = _mapper.ConfigurationProvider.GetAllTypeMaps().First(t => t.SourceType == typeParameterType);
var destType = destinationMap.DestinationType;
//Map with destination type
var eventMapped = _mapper.Map(@event, typeParameterType, destType);
//Get repository register in services
var repository = typeof(ICarrierEventRepository<>).MakeGenericType(destType);
dynamic repo = scope.ServiceProvider.GetRequiredService(repository);
//Insert on database
await repo.InsertOneAsync((dynamic)eventMapped);
//Get generate id
return ((dynamic)eventMapped).Id.ToString();
}
}