Информация об изменениях

Сообщение Интерфейс на событиях от 16.06.2015 9:23

Изменено 16.06.2015 9:24 tyomchick

История такая.
Сделал я класс, который реализует работу с пулом модемов.
  Интерфейс у него приблизительно такой:
public class ModemsPool : IEnumerable<Modem>, IDisposable
{
        /// <summary>
        /// Инициировать соединение через пул модемов
        /// </summary>
        /// <param name="route">Модемный маршрут</param>
        /// <returns>true - если возможна установка соединения, иначе false </returns>
    public bool InitConnect(ModemRoute route)
    {
    ...
    }  

    /// <summary>
    /// Событие установки соединения 
    /// </summary>    
    public event EventHandler<ModemsEventArgs> ModemConnected;

    /// <summary>
    /// Событие разрыва соединения 
    /// </summary>
    public event EventHandler<ModemsDisconnectedEventArgs> ModemDisconnected;

    /// <summary>
    /// Возникновение ошибки 
    /// </summary>
    public event EventHandler<ModemsExecutedErrorEventArgs> ModemExecutedError;

    /// <summary>
    /// Передача диагностической информации (жарнала)
    /// </summary>
    public event EventHandler<ModemsMessageEventArgs> ModemMessage;  
}

Смысл его работы такой:
1. Потребитель вызывает InitConnect, который запускает асинхронный процесс установки соединения через свободный модем или ставит запрос в очередь на ожидание освобождения модема;
2. По факту установки/неудачи установки соединения, инициируется соответствующее событие, которое помимо прочего возвращает объект Modem, который содержит методы для работы с модемом (реализует Stream для прокачки данных через модем, содержит функцию разрыва соединения и прочее...).

Этот класс успешно использовался, поверх него была накручено логика опроса оборудования через пул модемов ....

Но вот так получилось, что один пул нужно пользовать из нескольких сборок в рамках одного процесса. Т.е. пул модемов один, а логика поверх разная.
Если конкретно, то ряд устройств реализуют хитрожопый протокол работы по GPRS. На них нужно позонить, они определяют номер, бросают трубу, а сами по номеру из своей таблицы выбирают адрес сервера и порт, и коннектятся на него.

Ну в общем я вынес класс в отдельную сборку, сделал из пула сингтон.
Но вот беда, в рамках одного процесса несколько сборок пользуют один объект, но при этом все получают все события. И свои и чужие.
А нужно бы сделать, что бы каждый клиент получал свои события.
Понятно, что изначально дизайн был косячный, но я чего то не сварю как его красиво переделать.

На уровне ModemsPool я могу отличить одних клиентов от других, т.к. фактический тип ModemRoute них будет разный и для меня вполне применимо допущение, что только один клиент будет использовать определенный тип ModemRoute. Но как без большого гемороя сделать селективную инициацию событий пока не понял.

Подскажите пожалуйста.
Можем от событий совсем стоит отказаться.
Интерфейс на событиях
История такая.
Сделал я класс, который реализует работу с пулом модемов.
  Интерфейс у него приблизительно такой:
public class ModemsPool : IEnumerable<Modem>, IDisposable
{
        /// <summary>
        /// Инициировать соединение через пул модемов
        /// </summary>
        /// <param name="route">Модемный маршрут</param>
        /// <returns>true - если возможна установка соединения, иначе false </returns>
    public bool InitConnect(ModemRoute route)
    {
    ...
    }  

    /// <summary>
    /// Событие установки соединения 
    /// </summary>    
    public event EventHandler<ModemsEventArgs> ModemConnected;

    /// <summary>
    /// Событие разрыва соединения 
    /// </summary>
    public event EventHandler<ModemsDisconnectedEventArgs> ModemDisconnected;

    /// <summary>
    /// Возникновение ошибки 
    /// </summary>
    public event EventHandler<ModemsExecutedErrorEventArgs> ModemExecutedError;

    /// <summary>
    /// Передача диагностической информации (журнала)
    /// </summary>
    public event EventHandler<ModemsMessageEventArgs> ModemMessage;  
}

Смысл его работы такой:
1. Потребитель вызывает InitConnect, который запускает асинхронный процесс установки соединения через свободный модем или ставит запрос в очередь на ожидание освобождения модема;
2. По факту установки/неудачи установки соединения, инициируется соответствующее событие, которое помимо прочего возвращает объект Modem, который содержит методы для работы с модемом (реализует Stream для прокачки данных через модем, содержит функцию разрыва соединения и прочее...).

Этот класс успешно использовался, поверх него была накручено логика опроса оборудования через пул модемов ....

Но вот так получилось, что один пул нужно пользовать из нескольких сборок в рамках одного процесса. Т.е. пул модемов один, а логика поверх разная.
Если конкретно, то ряд устройств реализуют хитрожопый протокол работы по GPRS. На них нужно позонить, они определяют номер, бросают трубу, а сами по номеру из своей таблицы выбирают адрес сервера и порт, и коннектятся на него.

Ну в общем я вынес класс в отдельную сборку, сделал из пула сингтон.
Но вот беда, в рамках одного процесса несколько сборок пользуют один объект, но при этом все получают все события. И свои и чужие.
А нужно бы сделать, что бы каждый клиент получал свои события.
Понятно, что изначально дизайн был косячный, но я чего то не сварю как его красиво переделать.

На уровне ModemsPool я могу отличить одних клиентов от других, т.к. фактический тип ModemRoute них будет разный и для меня вполне применимо допущение, что только один клиент будет использовать определенный тип ModemRoute. Но как без большого гемороя сделать селективную инициацию событий пока не понял.

Подскажите пожалуйста.
Можем от событий совсем стоит отказаться.