2010-07-05 5 views
7

Это может показаться немного странным, но мне действительно нужно создать обходной путь для очень сложного дуплексного управления связью на C#, особенно для того, чтобы заставить других разработчиков соблюдать принцип DRY.C#: использование типа «я» в качестве общего параметра?

Так что я делаю это, чтобы иметь на основе многотонные типа, который выглядит следующим образом:

internal sealed class SessionManager<T> where T : DuplexServiceBase 

который не является проблемой вообще - до сих пор.

Однако, как только я хочу, чтобы услуги (я буду с одного экземпляра на сессии) регистрируются с SessionManager, хлопот начинается:

internal abstract class DuplexServiceBase : MessageDispatcherBase<Action> 

(MessageDispatcherBase есть класс шахты который создает поток и асинхронно отправляет сообщения).

Я хочу иметь метод, который выглядит следующим образом:

protected void ProcessInboundMessage() 
    { 
     // Connect 
     SessionManager<self>.Current.Connect(this); 
    } 

... но проблема в том, - как бы я добраться до «я»?

Мне действительно нужны отдельные диспетчеры сеансов для каждого класса обслуживания, потому что у всех есть свои собственные уведомления (в основном это очень раздражающие «NotifyAllClients» - метод, из-за которого мы хотим вытащить собственные волосы за последние часы) для лечения отдельно.

У вас есть ЛЮБЫЕ идеи?

Я не хочу использовать «AsyncPattern = true», кстати ... это потребовало бы, чтобы я отказался от типа безопасности, соблюдения принудительных контрактов (это приведет к очень плохому обращению с системой связи, которую я устанавливаю здесь) и потребует отказа от принципа СУХОЙ, во всем этом будет много повторяющегося кода, и это то, о чем я серьезно нахмурился.

Edit:

Я нашел наилучшее решение, благодаря ответам здесь - это УДЛИНИТЕЛЯ МЕТОД, хе-хе ...

public static SessionManager<T> GetSessionManager<T>(this T sessionObject) 
     where T : DuplexServiceBase 
    { 
     return SessionManager<T>.Current; 
    } 

я могу использовать это так:

GetSessionManager().Connect(this); 

Миссия выполнена. :-D

Этот метод (принадлежит DuplexServiceBase) дает мне диспетчер сеансов, с которым я хочу работать. Отлично! :-)

ответ

15

Я бы написать вспомогательный метод:

static class SessionManager { // non-generic! 
    static void Connect<T>(T item) where T : DuplexServiceBase { 
     SessionManager<T>.Current.Connect(item); 
    } 
} 

и использовать SessionManager.Connect(this), который будет фигурировать его автоматически с помощью универсального логического вывода типа.

+0

ты гений, я хотел бы дать вам +100, если бы я мог за этот ответ. Большое спасибо! –

+0

Несомненно 'SessionManager .Current.Connect (item);'? –

+0

Хе-хе, мне пришлось заменить «это» на «предмет», конечно. :-) –

3

Вы можете обернуть вызов в общий метод, таким образом, воспользовавшись умозаключения типа компилятора:

private static void ConnectSessionManager<T>(T service) 
{ 
    SessionManager<T>.Current.Connect(service) 
} 

protected void ProcessInboundMessage() 
{ 
    // Connect 
    ConnectSessionManager(this); 
} 
Смежные вопросы