城堡界面代理与动态目标

时间:2014-03-19 21:51:31

标签: c# signalr signalr-hub castle-dynamicproxy

我正在尝试使用Castle DynamicProxy来实现SignalR Hub的类型安全版本。 目标是当我使用Clients.All而不是获得动态对象时,我有一个可以使用的界面。

目前代码相当苛刻,但我想证明它在我遇到麻烦之前会有效:

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);
        }

现在,当我返回代理时,它失败了,因为目标没有实现接口。

是否有一种简单的方法可以实现这一目标,或者我应该使用InterfaceProxyWithoutTarget并使用拦截器将调用连接到动态。

1 个答案:

答案 0 :(得分:1)

你似乎走在了正确的轨道上。

这是SignalR 2.1中发布的功能。您可以在此处查看其实施方式:https://github.com/SignalR/SignalR/commit/3c4b8794b0f512daec677110a8e41ac717514584

虽然使用Castle DynamicProxy可能有办法实现这一点,但使用ImpromptuInterface可能更简单。

TypedClientBuilder<T>.Build(_dynamicContext...)的每次通话都可以替换为Impromptu.ActLike<T>(_dynamicContext...)。在您的情况下,对Impromptu.ActLike的调用将替换proxyGen.CreateInterfaceProxyWithTarget

如果您真的喜欢冒险,可以试用已经包含该功能的SignalR nightlies from MyGet