我可以在表示层中使用领域层实体的类型吗?

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();
   }
}