Код, о котором идет речь, написан роботом (CodeSmith), и его трудно поддерживать.Это выглядит примерно так:
public AddressProgramTemplate GetById(System.Int32 _id) {
try {
return Service.GetById(_id);
} catch (FaultException<ErrorInfo> ex) {
throw new ProxyServerBusinessException(ex.Detail);
} catch (FaultException) {
throw new ProxyServerBusinessException(null);
} catch (EndpointNotFoundException ex) {
throw new ProxyServerTechnicalException<EndpointNotFoundException>(ex);
} catch (CommunicationObjectFaultedException ex) {
throw new ProxyServerTechnicalException<CommunicationObjectFaultedException>(ex);
} catch (CommunicationException ex) {
throw new ProxyServerTechnicalException<CommunicationException>(ex);
} catch (ObjectDisposedException ex) {
throw new ProxyServerTechnicalException<ObjectDisposedException>(ex);
} catch (TimeoutException ex) {
throw new ProxyServerTechnicalException<TimeoutException>(ex);
}
}
Как вы можете догадаться, это код прокси WCF на стороне клиента, и все эти строки повторяются для каждого метода обслуживания (и их много).Что хорошо для робота, так это печаль для меня, поэтому я начал его реорганизовывать.Прежде всего, логика и обработка исключений делегируются в Microsoft Enterprise Library, а общий код переносится в базовый класс:
public TResult WrapServiceMethod<TResult>(Func<TResult> serviceMethod) {
TResult result = default(TResult);
try {
result = serviceMethod();
} catch (Exception ex) {
bool rethrow = ExceptionManager.HandleException(ex, ExceptionPolicyNames.ClientRequestPolicy);
if (rethrow) throw;
}
return result;
}
Пока все хорошо, уродливая куча try / catch превращается в аккуратную строку:
return WrapServiceMethod<AddressProgramTemplate>(() => Service.GetById(_id));
Немного усилий и пустых методов.Проблема возникает, когда вызовы службы используют out
параметры:
public void GetPeriod(AddressProgram program, out DateTime startDate, out DateTime endDate){
WrapServiceMethod(() => Service.GetPeriod(program, out startDate, out endDate));
}
В результате " Невозможно использовать параметр refDate или out 'endDate' внутри анонимного метода, лямбда-выражения или выражения запроса "и я понимаю почему .
В идеале мне бы хотелось иметь возможность определять пользовательские блоки операторов, такие как while () или using (), чтобы я мог написать
wrapexception { ... }
и жить долго и счастливо, но я не думаю, что этот трюк возможен с .NET.Предполагая, что переписывание всех методов обслуживания без параметров out
является последним средством, есть ли у меня какие-либо другие варианты?