Основываясь на первом ответе, я пришел к этому решению, которое в общем случае оборачивает автоматически сгенерированные клиентские прокси, созданные svcutil.exe:
public class ProxyWrapper<T> where T : ICommunicationObject
{
private T _service;
public ProxyWrapper()
{
_service = CreateNewInstance();
}
public void Invoke(Action<T> action)
{
try
{
action(_service);
}
catch (MessageSecurityException)
{
if (_service.State != CommunicationState.Faulted)
{
throw;
}
_service.Abort();
_service = CreateNewInstance();
action(_service);
}
}
public TResult Invoke<TResult>(Func<T, TResult> func)
{
try
{
return func(_service);
}
catch (MessageSecurityException)
{
if (_service.State != CommunicationState.Faulted)
{
throw;
}
_service.Abort();
_service = CreateNewInstance();
return func(_service);
}
}
private T CreateNewInstance()
{
Type type = typeof(T);
return (T)type.GetConstructor(Type.EmptyTypes).Invoke(null);
}
}
Чтобы использовать это, все, что вам нужно сделать, это:
ProxyWrapper<ServiceClient> client = new ProxyWrapper<ServiceClient>();
client.Invoke(s => s.SomeAction());
int val = client.Invoke<int>(s => s.ReturnsAnInteger());
Примечание: Поскольку я использую конструктор по умолчанию только для клиентских прокси, это все, что поддерживается.