我有這個主類接收一個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