我正在使用Azure函数的CQRS设计模式。我通过我的HttpTrigger Azure函数获得动态请求对象。现在,我已经根据请求中的 "EventType "属性来映射我的命令。
这是我的Azure函数。
[FunctionName("ReceiveEvent")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("ReceiveEvent HTTP trigger function started processing request.");
log.LogInformation($"Pushing Events to Azure Blob on storage account :-{CloudConfigurationManager.GetSetting("AzureWebJobsStorage")}");
IActionResult actionResult = null;
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
var eventType = EventType.Unknown;
string eventTypeValue = data.EventType;
Enum.TryParse(eventTypeValue, true, out eventType);
switch (eventType)
{
case EventType.CARD_BLOCK:
command = _cardBlockCommandMapper.Map(data);
break;
case EventType.CARD_CANCEL:
command = _cardCancelCommandMapper.Map(data);
break;
}
return actionResult;
这是我的命令映射器。
public class CardBlockCommandMapper : ICardBlockCommandMapper
{
public CardBlockCommand Map(dynamic data)
{
return new CardBlockCommand
{
Message = data.Message,
ModifiedByName = data.ModifiedByName
};
}
}
命令。
public abstract class Command
{
public virtual EventType EventType { get; set; }
}
public class CardBlockCommand : Command
{
public override EventType EventType => EventType.CARD_BLOCK;
public string ModifiedByName { get; set; }
public string Message { get; set; }
}
public class CardCancelledCommand:Command
{
public override EventType EventType => EventType.CARD_CANCEL;
public string Message { get; set; }
public List<string> MetaData { get; set; }
}
这是我的命令处理程序
public class CardBlockCommandHandler : ICommandHandler<CardBlockCommand>
{
private readonly IAzureBlobStorage _azureBlobStorage;
public CardBlockCommandHandler(IAzureBlobStorage azureBlobStorage)
{
_azureBlobStorage = azureBlobStorage;
}
public void Handle(CardBlockCommand command)
{
try
{
//TODO: Store into blob
//_azureBlobStorage.UploadMessageContentAsync(storageConnectionString: string.Empty,
// storageContainerName: string.Empty, blobName: string.Empty, content: string.Empty);
throw new NotImplementedException();
}
catch
{
}
}
}
我的问题是,我总共有15种不同类型的事件类型。我是否需要为每个类型创建一个单独的命令映射器?或者有什么更好的方法吗?
正如@Jochem Van Hespen所提到的,最简单的方法是将json反序列化为基于Enum值的具体类型。
分析一下这段代码,看看对你来说是否是一个更好的解决方案。
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace TestAPI
{
public abstract class Command
{
public virtual EventType EventType { get; set; }
}
public class CardBlockCommand : Command
{
public override EventType EventType => EventType.CARD_BLOCK;
public string ModifiedByName { get; set; }
public string Message { get; set; }
}
public class CardCancelledCommand : Command
{
public override EventType EventType => EventType.CARD_CANCEL;
public string Message { get; set; }
public List<string> MetaData { get; set; }
}
public enum EventType
{
CARD_BLOCK,
CARD_CANCEL,
Unknown
}
public class Program
{
public static void Main(string[] args)
{
var requestBody =
@"{ eventType: ""CARD_BLOCK"", message: ""message"", modifiedByName: ""ModifiedByName""}"; // sample response (json) from request
dynamic data = JsonConvert.DeserializeObject(requestBody);
string eventTypeValue = data.EventType;
Enum.TryParse(eventTypeValue, true, out EventType eventType);
switch (eventType)
{
case EventType.CARD_BLOCK:
CardBlockCommand cardBlockCommand = JsonConvert.DeserializeObject<CardBlockCommand>(requestBody);
// handler.Handle(cardBlockCommand)
break;
case EventType.CARD_CANCEL:
CardCancelledCommand cardCancelledCommand = JsonConvert.DeserializeObject<CardCancelledCommand>(requestBody);
// handler.Handle(cardCancelledCommand)
break;
}
}
}
}