我有这个主类接收一个queuemessage,然后使用其他几个类来做一些工作。所有这些其他类自己使用一些较低类,最终数据被写入数据库或发送到wcf服务。异常和耦合
根据较低类别的结果,主类必须决定是否删除queuemessage,或将其放在队列中,或者将它发送到一个deadletterqueue。
例如,如果数据库不可访问,则可以将queuemessage放置在队列中以稍后再试。但是,如果wdcf服务返回它不接受某些数据,则必须将该消息发送到deadletterqueue。
我有一对夫妇的方式来实现这样的场景:
- 抛出异常,只有处理它们在主类。
- 抛出异常,但在每个调用类中捕获它们。并重新抛出一个新的异常
- 返回结果的对象这表明错误/成功状态
这是我对场景的想法:
如果最低的一个类抛出一个异常,而主要阶级必须处理它,它将主要阶级一直耦合到最低阶级。如果其中一个最低类决定更改异常,则必须更改主类异常处理。
没有什么好方法让上层类知道从C#中的被调用类抛出哪些异常。
这是我更喜欢的。每个被调用的方法都可以返回一个结果对象,一个枚举指示成功或失败,以及失败类型。
所以,我的首选方法是选项3,但我不知道这是否在架构上可以接受。或者如果有更好的方法。
代码
这是代码(以简化形式)看起来像:
QueueHandler
private static void HandleQueueMessage(Message message)
{
var deliveryOrder = deserialize(message.body);
var deliveryOrderHandler = new DeliveryOrderHandler();
var result = deliveryOrderHandler.Execute(deliveryOrder.PubId);
switch (result)
{
case DeliveryOrderHandlerResult.DeliverySucceeded:
break;
case DeliveryOrderHandlerResult.FataleErrorInExternalSystem:
case DeliveryOrderHandlerResult.MAndatoryDocuhmentTransformationFailed:
SendDeliveryOrderToDeadletterQueue(deliveryOrder);
break;
default:
deliveryOrder.AbortCount = deliveryOrder.AbortCount + 1;
ResendDeliveryOrderToQueue(deliveryOrder);
break;
}
}
DeliveryOrderHandler
private DeliveryOrderHandlerResult Execute(long pubId)
{
DeliveryOrderHandlerResult deliveryOrderHandlerResult;
var transformationResult = GetTransformationResultaat(pubId);
if (transformationResult == TransformationResult.Success)
{
var deliveryResult = DeliverDocumentToExternalSystem(pubId);
if (deliveryResult.Status == DeliveryResult.Success)
{
SaveDeliveryResult(pubId, deliveryResult);
}
deliveryOrderHandlerResult = deliveryResult.Status;
}
else
{
switch (transformationResult)
{
case TransformationResult.NotStarted:
deliveryOrderHandlerResult = DeliveryOrderHandlerResult.TransformationNotStarted;
case TransformationResult.Busy:
deliveryOrderHandlerResult = DeliveryOrderHandlerResult.TransformationBusy;
case TransformationResult.MandatoryTransformationFailed:
deliveryOrderHandlerResult = DeliveryOrderHandlerResult.MandatoryTransformationFailed;
default:
throw new Exception(--unknown enum value --);
}
}
return deliveryOrderHandlerResult;
}
DeliverDocumentToExternalSystem
pseudo:
- Create Delivery package by reading data from database and transformed files from disk
- Send package to external system
正如你可以看到有很多可能出错;数据库连接失败,wcf服务调用失败,文件不存在等。
我希望我能避免这种情况:
QueueHandler
private static void HandleQueueMessage(Message message)
{
var deliveryOrder = deserialize(message.body);
var deliveryOrderHandler = new DeliveryOrderHandler();
try
{
var result = deliveryOrderHandler.Execute(deliveryOrder.PubId);
switch(result)
{
case DeliveryOrderHandlerResult.Success:
// remove message from queue
case DeliveryOrderHandlerResult.NotStarted:
// resent message to queue
case DeliveryOrderHandlerResult.MandatoryTransformationFailed:
// send message to deadletterqueue
case ...
// handle
case ...
// handle
}
}
pseudo catches:
catch (DatabaseNotFoundexception ex)
{
// resent message to queue
}
catch (ExternalWcfServiceDownException ex)
{
// resent message to queue
}
catch (FileNotFoundException ex)
{
// send message to deadletterqueue
}
catch (...)
{
// handle
}
catch (...)
{
// handle
}
}
你有什么迄今为止关于代码,你可以展示,从而使他人可以提供一个更好的方法..如果您确实张贴了这种性质..它可能会在计算器上的代码审查部分可以提供最好的服务代码。 – MethodMan