Created
February 3, 2018 14:46
-
-
Save Rene-Sackers/3df309916ab2ed55d8ffe879cbc3aea6 to your computer and use it in GitHub Desktop.
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
[Serializable] | |
public class TypedHubClientInterceptor : IInterceptor | |
{ | |
public delegate void MethodCalledHandler(MethodInfo methodInfo, params object[] args); | |
public void Intercept(IInvocation invocation) => | |
MethodCalled?.Invoke(invocation.Method, invocation.Arguments); | |
public event MethodCalledHandler MethodCalled; | |
} | |
public class TypedHubClient<TClient> where TClient : class | |
{ | |
private readonly HubConnection _hubConnection; | |
private readonly TClient _onHandlerClient; | |
private readonly Dictionary<string, Tuple<MethodInfo, object>> _onHandlers = new Dictionary<string, Tuple<MethodInfo, object>>(); | |
private TaskCompletionSource<string> _getOnHookMethodName; | |
public TClient Client { get; } | |
public TypedHubClient(HubConnection hubConnection) | |
{ | |
_hubConnection = hubConnection; | |
var proxyGenerator = new ProxyGenerator(); | |
var proxyInterceptor = new TypedHubClientInterceptor(); | |
var onHookProxyInterceptor = new TypedHubClientInterceptor(); | |
proxyInterceptor.MethodCalled += ProxyInterceptorOnMethodCalled; | |
onHookProxyInterceptor.MethodCalled += OnHookProxyInterceptorOnMethodCalled; | |
Client = proxyGenerator.CreateInterfaceProxyWithoutTarget<TClient>(proxyInterceptor); | |
_onHandlerClient = proxyGenerator.CreateInterfaceProxyWithoutTarget<TClient>(onHookProxyInterceptor); | |
} | |
private void ProxyInterceptorOnMethodCalled(MethodInfo methodInfo, params object[] args) => | |
_hubConnection.InvokeAsync(methodInfo.Name, args); | |
private void OnHookProxyInterceptorOnMethodCalled(MethodInfo methodInfo, params object[] args) | |
{ | |
_getOnHookMethodName?.TrySetResult(methodInfo.Name); | |
_hubConnection.On( | |
methodInfo.Name, | |
methodInfo.GetParameters().Select(p => p.ParameterType).ToArray(), | |
objects => HandleHubConnectionClientOnEvent(methodInfo.Name, objects) | |
); | |
} | |
private Task HandleHubConnectionClientOnEvent(string methodName, object[] args) | |
{ | |
if (!_onHandlers.ContainsKey(methodName)) | |
return Task.CompletedTask; | |
var methodHandling = _onHandlers[methodName]; | |
return (Task)methodHandling.Item1.Invoke(methodHandling.Item2, args); | |
} | |
public async Task On(Action<TClient> clientAction, Func<object[], Task> handler, object handlerInstance) | |
{ | |
_getOnHookMethodName = new TaskCompletionSource<string>(); | |
clientAction(_onHandlerClient); | |
var methodName = await _getOnHookMethodName.Task; | |
_onHandlers.Add(methodName, new Tuple<MethodInfo, object>(handler.Method, handlerInstance)); | |
} | |
public async Task On<T1>(Action<TClient> clientAction, Func<T1, Task> handler, object handlerInstance) | |
{ | |
_getOnHookMethodName = new TaskCompletionSource<string>(); | |
clientAction(_onHandlerClient); | |
var methodName = await _getOnHookMethodName.Task; | |
_onHandlers.Add(methodName, new Tuple<MethodInfo, object>(handler.Method, handlerInstance)); | |
} | |
public async Task On<T1, T2>(Action<TClient> clientAction, Func<T1, T2, Task> handler) | |
{ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment