我正在尝试使用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并使用拦截器将调用连接到动态。
答案 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。