Last active
June 14, 2017 03:26
-
-
Save analogrelay/1c3b1ad0fe1b7c488ed9a31faca500ad to your computer and use it in GitHub Desktop.
Hub<anything>
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
// Treat Client Proxies kinda like Formatters; Hub<T> just tries to get an IClientProxyFactory<T> from DI and invokes it. | |
// We provide one for `dynamic` and another that can be registered as an open-generic and generated code at runtime. | |
// Users can provide custom implementations for anything. | |
public interface IClientProxy { | |
Task InvokeAsync(string method, params object[] args); | |
} | |
public interface IClientProxyFactory<T> { | |
T CreateProxy(IClientProxy proxy); // <-- may need some caching logic | |
} | |
public class HubProxies { | |
public IClientProxy All { get; } | |
public IClientProxy User(string userId); | |
public IClientProxy Group(string groupName); | |
public IClientProxy Client(string clientId); | |
} | |
public class HubProxies<T> { | |
private readonly IClientProxyFactory<T> _factory; | |
private readonly HubProxies _proxies; | |
public HubProxies(IClientProxyFactory<T> factory, HubProxies proxies) { | |
_factory = factory; | |
_proxies = proxies; | |
} | |
public new T All => _factory.CreateProxy(_proxies.All); | |
public new T User(string userId) => _factory.CreateProxy(_proxies.User(userId)); | |
public new T Group(string groupName) => _factory.CreateProxy(_proxies.Group(groupName)); | |
public new T Client(string clientId) => _factory.CreateProxy(_proxies.Client(clientId)); | |
} | |
public abstract class Hub { | |
public HubProxies Clients { get; } | |
public virtual void Initialize(IServiceProvider services) {} | |
} | |
public abstract class Hub<T> : Hub { | |
private IHubClientAdaptor<T> _adaptor; | |
public new HubProxies<T> Clients => new HubProxies(_adaptor, base.Clients); | |
public override void Initialize(IServiceProvider services) { | |
_adaptor = services.GetRequiredService<IHubClientAdaptor<T>>(); | |
} | |
} | |
public class DynamicClientProxyFactory : IClientProxyFactory<dynamic> { | |
public dynamic CreateProxy(IClientProxy client) => new DynamicClientProxy(client); // <-- implements DynamicObject by wrapping IClientProxy | |
} | |
public class GeneratedClientProxyFactory<T> : IClientProxyFactory<T> { | |
public T CreateProxy(IClientProxy client) { | |
// Use Reflection Emit to generate a class implementing T, then create an instance and return it. | |
} | |
} | |
public class MyManualClientProxyFactory : IClientProxyFactory<IChatProxy> { | |
public IChatProxy CreateProxy(IClientProxy client) { | |
// A user could just create their own adaptor manually, or our Proxy generator could do it for them? | |
} | |
} | |
public static class SignalRServiceCollectionExtensions { | |
public static void AddSignalR(this IServiceCollection services) { | |
// ... other stuff ... | |
services.AddSingleton<IClientProxyFactory<dynamic>, DynamicClientProxyFactory>(); | |
services.AddSingleton<IClientProxyFactory<>, GeneratedClientProxyFactory<>>(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment