Software requirements is asking all DTOs contain their own Response Class. So developers basically wrap Product DTO in Base Response class. We have whole list of class areas, requiring hundreds of classes for Product, Sales, Customer, etc all doing same thing, per below. Client does not want to wrap as BaseResponse<Product> or BaseResponse<IEnumerable<ProductDto>
since it is nested/unreadable.
Is there method to wrap/create variable classes and readable, without manually writing 100s of class (maybe extension method, dynamic class, variable, not sure, open to any method)?
Note: Response classes can be different, so want to give programmer option to create automated standard class, or create own customized manual class, so two options can exist.
Current Code:
Product DTO Class:
public class ProductDto
{
public int ProductId { get; set;},
public string ProductName { get; set;},
public string ProductDescription { get; set;},
public float SalesAmount { get; set;}
}
BaseResponse:
public class BaseResponse<T>
{
[Required, ValidateObject]
public T Body { get; set; }
public bool HasError { get; set; }
public string Error { get; set; }
}
Individual Response:
public class GetAllProductResponse : BaseResponse<IEnumerable<ProductDto>>
{
}
public class GetProductResponse : BaseResponse<ProductDto>
{
}
public class UpdateProductResponse : BaseResponse<ProductDto>
{
}
Proposed Code:
public static class ResponseExtensions
{
public static BaseRequestResponse<T> GetAllResponse<T> (this T obj) where T:class
{
return BaseRequestResponse<IEnumerable<T>>;
}
public static BaseRequestResponse<T> GetResponse<T>(this T obj) where T : class
{
return BaseRequestResponse<T>;
}
public static BaseRequestResponse<T> UpdateResponse<T>(this T obj) where T : class
{
return BaseRequestResponse<T>;
}
}
So the code will now look as this,
ProductDTO.GetAllResponse
ProductDTO.GetResponse
ProductDTO.UpdateResponse
Is this a good method, architecturally sound, or should something else be applied?
This probably will not work, since any middle tier layer sending/receiving response will need refer to as BaseResponse< IEnumerable< ProductDto >, etc.
By the way,if going this route, receiving compilation error here
'BaseRequestResponse<T>' is a type, which is not valid in the given context
Update:
This is how we use DTO and Response
public async Task<ActionResult<GetProductResponse>> GetByProduct(int id)
{
try
{
var productdto = await productAppService.GetProductById(id);
var response = new GetProductResponse { Body = productdto };
return Ok(response);
}
catch (Exception ex)
{
logger.LogError(ex, ex.Message);
var response = new GetDocumentResponse { HasError = true, Error = ex.Message };
return StatusCode(StatusCodes.Status500InternalServerError, response);
}
}
See Question&Answers more detail:
os