Прокси интерфейса замка с динамической целью

Я пытаюсь использовать Castle DynamicProxy для реализации типизированной версии SignalR Hub. Цель состоит в том, что когда я использую Clients. Вместо того, чтобы возвращать динамический объект, у меня есть интерфейс для использования.

Код на данный момент довольно хакерский, но я хотел доказать, что он будет работать, прежде чем я буду стараться сделать его красивым:

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 и использование перехватчика для подключения вызова к динамическому.


person Community    schedule 19.03.2014    source источник


Ответы (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 от MyGet, в которые уже включена эта функция. .

person halter73    schedule 19.03.2014
comment
Хорошо, поэтому, если я правильно понимаю, мне нужно будет использовать только решение ImpromptuInterface, если я использую Signal R 2.0. Если бы я использовал nightly или подождал до 2.1, меня накрыли? - person ; 20.03.2014
comment
Hub ‹T› должен быть в SignalR 2.1. Я не думаю, что еще была объявлена ​​дата релиза. - person halter73; 20.03.2014
comment
Это нормально, это означало скорее доказательство концепции, чем фактической функциональности, тот факт, что это вообще делается, меня очень взволновал. Я смогу вернуться к другому прокси-интерфейсу, о котором я писал на SO, а также очистить его. - person ; 20.03.2014