Created
June 6, 2014 13:26
-
-
Save jchapuis/b94e199ce9e790f011aa to your computer and use it in GitHub Desktop.
Higher order functions example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[RegisterAsImplementedInterfaces(PerOwnedType = typeof (IConnectionScope))] | |
internal class ResponseDispatcher : IResponseDispatcher | |
{ | |
private static readonly ILog Log = LogFactory.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | |
private readonly IRequestsPendingResponseRepository requestsPendingResponse; | |
private readonly IConnectionContext context; | |
public ResponseDispatcher(IRequestsPendingResponseRepository requestsPendingResponse, IConnectionContext context) | |
{ | |
this.requestsPendingResponse = requestsPendingResponse; | |
this.context = context; | |
} | |
public void DispatchResponse(Response response) | |
{ | |
DispatchOperations.DispatchResponse( | |
response, | |
RetrieveAndRemoveResponseHandlerWithId, | |
HandleUnexpectedResponse, | |
LogInvalidResponse, | |
LogErrorResponse); | |
} | |
private Option<ResponseHandlers> RetrieveAndRemoveResponseHandlerWithId(string id) | |
{ | |
return | |
requestsPendingResponse.RetrieveAndRemoveRequestWithId(id) | |
.Select(r => new ResponseHandlers | |
{ | |
HandleResponse = r.Response.SetResponse, | |
HandleException = r.Response.SetToException | |
}); | |
} | |
private void LogErrorResponse(Error error) | |
{ | |
context.Log(Log.ErrorFormat, "Received error response: code={0}, message={1}", error.Code, error.Message); | |
} | |
private void LogInvalidResponse(string response, XmlException exception) | |
{ | |
context.Log(Log.ErrorFormat, | |
"Received non-conforming response, parsing fails with {0}: {1}", | |
exception.Message, | |
response); | |
} | |
private void HandleUnexpectedResponse(Response response) | |
{ | |
context.Log(Log.ErrorFormat, | |
"Received unexpected response (id {0}): {1}", | |
response.Id, | |
response.Message); | |
} | |
} | |
internal static class DispatchOperations | |
{ | |
public static void DispatchResponse( | |
Response response, | |
Func<string, Option<ResponseHandlers>> retrieveResponseHandlersForId, | |
Action<Response> handleUnexpectedResponse, | |
Action<string, XmlException> logInvalidResponse, | |
Action<Error> logErrorResponse) | |
{ | |
retrieveResponseHandlersForId(response.Id) | |
.WhenHasValue( | |
handlers => | |
ReceiverOperations.CheckForErrorAndHandle( | |
response: response.Message, | |
handleError: error => | |
{ | |
logErrorResponse(error); | |
handlers.HandleException(new ErrorResponseException(error.Code, error.Message)); | |
}, | |
handleOther: handlers.HandleResponse, | |
handleException: (invalidPayload, exception) => | |
{ | |
logInvalidResponse(invalidPayload, exception); | |
handlers.HandleException(new InvalidResponseException(invalidPayload, exception)); | |
}) | |
) | |
.WhenEmpty(() => handleUnexpectedResponse(response)); | |
} | |
} | |
public static class ReceiverOperations | |
{ | |
public static void CheckForErrorAndHandle( | |
string response, | |
Action<Error> handleError, | |
Action<string> handleOther, | |
Action<string, XmlException> handleException) | |
{ | |
CheckForXml( | |
response, | |
xmlReader => | |
{ | |
if (xmlReader.Name == "error") | |
{ | |
var error = (XElement) XNode.ReadFrom(xmlReader); | |
handleError( | |
new Error | |
{ | |
Code = | |
(string) | |
error.Element("code") | |
.AsOption() | |
.ValueOrThrow(() => new XmlException("Missing error code")), | |
Message = | |
(string) | |
error.Element("message") | |
.AsOption() | |
.ValueOrThrow(() => new XmlException("Missing error message")), | |
}); | |
} | |
else | |
{ | |
handleOther(response); | |
} | |
}, | |
handleException); | |
} | |
private static void CheckForXml( | |
string message, | |
Action<XmlReader> handleXml, | |
Action<string, XmlException> handleXmlException) | |
{ | |
try | |
{ | |
using (var reader = XmlReader.Create(new StringReader(message))) | |
{ | |
reader.Read(); | |
handleXml(reader); | |
} | |
} | |
catch (XmlException e) | |
{ | |
handleXmlException(message, e); | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment