Я работаю над приложением C#, и у меня есть 2 (скоро будет 3, 4 и более) метода, которые имеют такую похожую структуру, что их просят преобразовать в нечто более общее c. Вот 2 образца, вы увидите сходство.
Метод 1:
public async Task<APIGatewayProxyResponse> McaEventStoreRecvdPointsCouponProxyResponse(APIGatewayProxyRequest request, ILambdaContext context)
{
try
{
string thisRequestId = Guid.NewGuid().ToString();
if (request.PathParameters.Any())
{
var cardNumber = request.PathParameters.FirstOrDefault(x => x.Key.ToLower() == "card_number").Value;
context.Logger.LogLine($"MCA Event store event [{cardNumber}]");
var restValueVoucher = JsonConvert.DeserializeObject<RootObjectRestValueVoucherPayload>(request.Body);
RestValueVoucherPayloadValidator validator = new RestValueVoucherPayloadValidator();
ValidationResult results = validator.Validate(restValueVoucher.Payload);
if (!results.IsValid) throw new SchemaValidationException(results.Errors);
var dbRestValueVoucher = restValueVoucher.Payload.Convert(restValueVoucher.Payload);
dbRestValueVoucher.CardNumber = cardNumber;
loyaltyContext.Add(dbRestValueVoucher);
int rowsAffected = await loyaltyContext.SaveChangesAsync();
context.Logger.LogLine($"Database changes applied {rowsAffected}");
return GenerateResponse(HttpStatusCode.OK, new EventStoreResponse(context,
RequestResponseTypes.EVENT_STORE, thisRequestId,
restValueVoucher.Payload));
}
else
{
return GenerateResponse(HttpStatusCode.OK, new TestResponse(context, RequestResponseTypes.TEST_REQUEST));
}
}
catch (SchemaValidationException schemaEx)
{
context.Logger.LogLine(schemaEx.Message);
return GenerateResponse(HttpStatusCode.BadRequest, schemaEx);
}
catch (Exception ex)
{
context.Logger.LogLine($"{ex}");
LcsException lcsException = new LcsException(ex);
return GenerateResponse(HttpStatusCode.BadRequest,
lcsException);
}
}
Метод 2:
public async Task<APIGatewayProxyResponse> McaEventStoreTierChangeProxyResponse(APIGatewayProxyRequest request, ILambdaContext context)
{
try
{
string thisRequestId = Guid.NewGuid().ToString();
if (request.PathParameters.Any())
{
var cardNumber = request.PathParameters.FirstOrDefault(x => x.Key.ToLower() == "card_number").Value;
context.Logger.LogLine($"MCA Event store event [{cardNumber}]");
var tierChange = JsonConvert.DeserializeObject<RootObjectTierChangePayload>(request.Body);
TierChangePayloadValidator validator = new TierChangePayloadValidator();
ValidationResult results = validator.Validate(tierChange.Payload);
if (!results.IsValid) throw new SchemaValidationException(results.Errors);
var dbTierChange = tierChange.Payload.Convert(tierChange.Payload);
dbTierChange.CardNumber = cardNumber;
loyaltyContext.Add(dbTierChange);
int rowsAffected = await loyaltyContext.SaveChangesAsync();
context.Logger.LogLine($"Database changes applied {rowsAffected}");
return GenerateResponse(HttpStatusCode.OK, new EventStoreResponse(context,
RequestResponseTypes.EVENT_STORE, thisRequestId,
tierChange.Payload));
}
else
{
return GenerateResponse(HttpStatusCode.OK, new TestResponse(context, RequestResponseTypes.TEST_REQUEST));
}
}
catch (SchemaValidationException schemaEx)
{
context.Logger.LogLine(schemaEx.Message);
return GenerateResponse(HttpStatusCode.BadRequest, schemaEx);
}
catch (Exception ex)
{
context.Logger.LogLine($"{ex}");
LcsException lcsException = new LcsException(ex);
return GenerateResponse(HttpStatusCode.BadRequest,
lcsException);
}
}
Я начал работать над обобщенным методом c и дошел до этого:
private static TPayload ProcessTest<TPayload, TEvent>(TPayload payload, TEvent myevent, string body, AbstractValidator<TPayload> validator)
where TPayload : Payload
where TEvent : IEventStore
{
var test = JsonConvert.DeserializeObject<TPayload>(body);
ValidationResult results = validator.Validate(?)
}
Моя проблема связана с рефакторингом этой строки на данный момент: ValidationResult results = validator.Validate (tierChange.Payload ). tierChange - это JSON 'Root объект', который позволяет мне принимать входящие JSON в следующем формате:
{
"Message": {
"message-id": 1000,
"old-tier": "SISTERCLUB",
"new-tier": "DIAMOND",
"timestamp-of-change": "2020-07-27T00:00:00",
"anniversary-date": "2020-07-28T00:00:00"
}
}
Структура очень похожа на входящую JSON для метода 1, который равен:
{
"Message": {
"message-id": 10000,
"redeemed-voucher-instance-id":123,
"new-voucher-instance-id":1234,
"initial-voucher-value": 5.00,
"rest-voucher-value":15.00,
"valid-from": "2020-07-27T00:00:00",
"valid-to": "2021-07-27T00:00:00",
"description": "$5 BIRTHDAY VOUCHER",
"unit": "AUD"
}
}
.Payload используется для доступа к содержимому внутри объекта root в обоих случаях (содержимое, уникальное для каждого объекта). Вот пример объекта Tier Change Root и Payload (кроме различных свойств внутри Payload, другой объект такой же).
Объект root:
public class RootObjectTierChangePayload
{
[JsonProperty(PropertyName = "Message")]
public TierChangePayload Payload { get; set; }
}
И внутренний объект:
public partial class TierChangePayload : Payload, ITransform<TierChangePayload, TierChange>, IEventStore
{
[JsonProperty(PropertyName = "message-id")]
public int MessageId { get; set; }
/// <summary>
/// </summary>
[JsonProperty(PropertyName = "old-tier")]
public string OldTier { get; set; }
/// <summary>
/// </summary>
[JsonProperty(PropertyName = "new-tier")]
public string NewTier { get; set; }
/// <summary>
/// </summary>
[JsonProperty(PropertyName = "timestamp-of-change")]
public DateTime TimestampOfChange { get; set; }
/// <summary>
/// </summary>
[JsonProperty(PropertyName = "anniversary-date")]
public DateTime AnniversaryDate { get; set; }
public TierChange Convert(TierChangePayload source)
{
TierChange tierChange = new TierChange
{
CreatedTimestamp = Functions.GenerateDateTimeByLocale(),
ChangeTimestamp = null,
AnniversaryDate = this.AnniversaryDate,
MessageId = this.MessageId,
NewTierId = this.NewTier,
OldTierId = this.OldTier
};
return tierChange;
}
public string ToJson()
{
throw new NotImplementedException();
}
}
Как мне настроить объекты, которые я использую, чтобы я мог лучше обобщить их для соответствия общему методу c? На данный момент я не могу получить доступ к .Payload в общем методе c.