I am trying to use Castle DynamicProxy to implement a typesafe version of a SignalR Hub. The goal being when I use Clients.All rather than getting a dynamic object back I have an interface to use.

The code is rather hacky at the moment but I wanted to prove that it will work before I go through the trouble of making it nice:

public interface IChatClient
{
    void broadcastMessage(string name, string message);
}

public class ChatHub : TypeSafeHub<IChatClient>
{
    public void Send(string name, string message)
    {
        Clients.All.broadcastMessage(name, message);
    }
}

public abstract class TypeSafeHub<TInterface> : Hub where TInterface:class
{
    public new TypeSafeHubCallerConnectionContext<TInterface> Clients
    {
        get
        {
            return new TypeSafeHubCallerConnectionContext<TInterface>(base.Clients);
        }
    }
}

public class TypeSafeHubCallerConnectionContext<T> where T:class
{
    private IHubCallerConnectionContext context;
    private ProxyGenerator proxyGen;

    public TypeSafeHubCallerConnectionContext(IHubCallerConnectionContext context)
    {
        this.context = context;
        proxyGen= new ProxyGenerator();
    }

    public T All
    {
        get
        {
            return proxyGen.CreateInterfaceProxyWithTarget<T>(context.All);
        }

Right now when I'm returning the proxy it fails because the target does not implement the interface.

Is there an easy way to achieve this goal or should I look at using an InterfaceProxyWithoutTarget and using an interceptor to wire up the call to the dynamic.

有帮助吗?

解决方案

You seem to be on the right track.

This is a feature slated for release in SignalR 2.1. You can look at how it is implemented here: https://github.com/SignalR/SignalR/commit/3c4b8794b0f512daec677110a8e41ac717514584

While there is likely a way to do this with Castle DynamicProxy, it might be simpler to use ImpromptuInterface.

Every call made to TypedClientBuilder<T>.Build(_dynamicContext...) could be replaced with Impromptu.ActLike<T>(_dynamicContext...). In your case, the call to Impromptu.ActLike would replace proxyGen.CreateInterfaceProxyWithTarget.

If you feel really adventurous, you can try out the SignalR nightlies from MyGet which already have the feature included.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top