Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我如何处理CQR的索赔检查_C#_Cqrs_Rebus - Fatal编程技术网

C# 我如何处理CQR的索赔检查

C# 我如何处理CQR的索赔检查,c#,cqrs,rebus,C#,Cqrs,Rebus,TL;博士: 1.我在创造一个反模式吗? 2.处理CQR索赔检查的最佳方式是什么 我在我的系统中有几个入口点(webapi传递json和xml),以及通过固定长度文件的文件系统 我正在使用带有MSMQ和Sql server的REBS来管理我的消息传递。数据可以大于4mb(如果我相信的话,MSMQ的最大消息大小)。当系统接收到一个文件时,我将其转换为一个流,并创建一个实现IAttachmentCommand的命令,如下所示: public interface IAttachmentCommand

TL;博士: 1.我在创造一个反模式吗? 2.处理CQR索赔检查的最佳方式是什么

我在我的系统中有几个入口点(webapi传递json和xml),以及通过固定长度文件的文件系统

我正在使用带有MSMQ和Sql server的REBS来管理我的消息传递。数据可以大于4mb(如果我相信的话,MSMQ的最大消息大小)。当系统接收到一个文件时,我将其转换为一个流,并创建一个实现IAttachmentCommand的命令,如下所示:

public interface IAttachmentCommand : ICommand
{
    Stream Attachment { get; }

    IClaimCheckCommand ToClaimCheck(string attachmentId);
}

public interface IClaimCheckCommand : ICommand
{
    string AttachmentId { get; }
}
public void Send<TCommand>(TCommand command) where TCommand : ICommand
{
  if (command is IAttachmentCommand)
  {
    var cmd = command as IAttachmentCommand;
    var task = CreateAttachment(cmd);  // method excluded, but persists to Rebus DataBus and returns AttachmentId
    var claimCheck = task.Result;
    _activator.Bus.Send(claimCheck);
  }
  else
  {
    _activator.Bus.Send(command);
  }
}
然后,我使用命令总线(使用Rebus)发送它。如果命令类型为IAttachmentCommand,我将在rebus databus表中创建一个附件,并在原始命令上使用ToClaimCheck返回一个新的IAttachmentCommand。AttachmentCommand实际上是原始命令的副本,只是它现在有attachmentId而不是数据

然后,我将调用我的Rebus总线和我的新附件ID,如下所示:

public interface IAttachmentCommand : ICommand
{
    Stream Attachment { get; }

    IClaimCheckCommand ToClaimCheck(string attachmentId);
}

public interface IClaimCheckCommand : ICommand
{
    string AttachmentId { get; }
}
public void Send<TCommand>(TCommand command) where TCommand : ICommand
{
  if (command is IAttachmentCommand)
  {
    var cmd = command as IAttachmentCommand;
    var task = CreateAttachment(cmd);  // method excluded, but persists to Rebus DataBus and returns AttachmentId
    var claimCheck = task.Result;
    _activator.Bus.Send(claimCheck);
  }
  else
  {
    _activator.Bus.Send(command);
  }
}
public void Send(TCommand命令),其中TCommand:ICommand
{
如果(命令为IAttachmentCommand)
{
var cmd=作为IAttachmentCommand的命令;
var task=CreateAttachment(cmd);//方法已排除,但会持续存在于Rebus数据总线并返回AttachmentId
var claimCheck=task.Result;
_激活器总线发送(索赔检查);
}
其他的
{
_激活器总线发送(命令);
}
}
这似乎是可行的,尽管我很高兴我的代码被撕成碎片。我可以发送命令,应用聚合根生成的事件,保存到事件存储等

我只需从webapi调用或文件系统中提取一个文件,创建一个命令,并使用命令总线发送它

在一个单独的windows服务中,我有一个命令调度器监视这些消息的MSMQ。当一条消息传入时,它将遍历有多少CommandValidationHandler来验证该命令。CommandValidationHandler实现以下功能:

public interface ICommandValidationHandler<in TCommand> where TCommand : ICommand
{
   ValidationResult Validate(TCommand command);
}
公共接口ICommandValidationHandler,其中TCommand:ICommand
{
验证结果验证(TCommand命令);
}
ValidationResult有效地返回错误集合。这些错误被记录下来,作为包含命令信息和错误的InvalidCommand事件发布-这允许我让正在侦听的任何订阅者接收事件-发送邮件或调用web服务等,以说明消息失败,并说明原因。如果命令无效,则引发异常,进程停止

我关心的是,在验证时,我有attachmentId,并且必须检索文件,然后对其进行验证,例如针对xsd进行验证

从这里开始,我需要将其反序列化为一个对象(通常是一个财务事务集合,其标题包含元数据,如事务数等),并对对象中的数据执行额外的验证

验证完成后,我需要迭代对象中的事务集合,并使用命令总线将它们发送到相关的有界上下文,然后进行进一步的处理

在本例中,我似乎会多次访问声明存储区—每个验证处理程序一次(虽然我想这可以通过一个组合的验证程序集合来解决),但在验证完成后,再次在命令处理程序中访问

在各种事件处理程序中,我都需要访问每次从声明存储中检索数据并多次反序列化所需的所有数据

我觉得这好像是代码的味道。在所有事件处理程序完成工作后,是否应该考虑第一次检索文件并从缓存中清除文件?


有谁有更好的建议吗?

根据我对您的问题的理解,问题实际上是:“我应该使用缓存机制来读取验证处理程序上的
声明存储
?”

在您的情况下,因为
声明存储中的数据是不可变的,所以只要需要,您就可以缓存它。这就是不变数据的美妙之处:它永远是可缓存的

要实现缓存机制,您可以在
声明存储
上使用decorator模式,并切换到
依赖项容器
中的
组合根
中的缓存版本。通过这种方式,您可以随时切换回未缓存的


如果验证后的数据没有任何变化,并且会随着时间的推移而重复,则可以对其进行更多的缓存,甚至可以对验证结果进行缓存。

如果使用缓存,是否存在缓存必须失效的情况?数据是不可变的,但可以从缓存中删除—例如,如果cpu开始受到1000条记录的过多命中,如果我决定在缓存中放置过期,或者一旦订阅消息的所有事件处理程序都收到它,就可以将其删除。我想即使在我有附件的情况下,保留对附件ID的引用也是明智的——这样,如果它已从缓存中删除,我就可以延迟加载它。缓存模式很好,但缓存的缺点是,当真相来源被保存时,缓存很难失效。如果这不是你的情况,那么使用它。