Прежде чем вы начнете читать, обратите внимание, что я включил весь код для полного примера, поэтому он может быть длинным.: D
Проблема
В настоящее время я работаю над проектом с использованием веб-служб Exchange (EWS), который отвечает за подписку на EWS, запрашивающую обратные вызовы для определенных событий всякий раз, когда в указанные почтовые ящики поступает новая почта.Однако у нас были проблемы с нашим почтовым сервером в течение нескольких недель.Поскольку наша реализация была так тесно связана с подключением Exchange к сети, мы не смогли продолжить работу.Именно тогда у меня появилась идея создать небольшую реализацию обработчика событий, которая могла бы работать с или без Exchange.Очевидно, что если бы Exchange не был в сети, мне пришлось бы вручную вызывать события.
Моя причина создания универсального интерфейса обработчика событий заключается в том, что я мог бы создать класс обработчика событий, который мог бы работать с Exchange или без него.Так что для реализации Exchange у меня будет IEventHander<>
.И для фиктивной реализации у меня будет EventHandlerBase<NotificationEventArgs, DisconnectEventArgs, ErrorEventArgs>
, что я и показал ниже.Кроме того, все объекты EventArgs из последнего являются пользовательскими без какой-либо функциональности.
См. Ниже то, что я имею до сих пор.
public interface IEventHandler
<TOnNotification, TOnDisconnect, TOnSubscriptionError>
where TOnNotification : EventArgs
where TOnDisconnect : EventArgs
where TOnSubscriptionError : EventArgs
{
event EventHandler<TOnNotification> OnNotification;
event EventHandler<TOnDisconnect> OnDisconnect;
event EventHandler<TOnSubscriptionError> OnSubscriptionError;
void OnNotificationEvent(object sender, TOnNotification args);
void OnDisconnectEvent(object sender, TOnDisconnect args);
void OnErrorEvent(object sender, TOnSubscriptionError args);
}
public abstract class EventHandlerBase<TOnNotification, TOnDisconnect, TOnError>
: IEventHandler<TOnNotification, TOnDisconnect, TOnError>
where TOnNotification : EventArgs
where TOnDisconnect : EventArgs
where TOnError : EventArgs
{
public event EventHandler<TOnNotification> OnNotification;
public event EventHandler<TOnDisconnect> OnDisconnect;
public event EventHandler<TOnError> OnSubscriptionError;
public abstract void OnNotificationEvent(object sender, TOnNotification args);
public abstract void OnDisconnectEvent(object sender, TOnDisconnect args);
public abstract void OnErrorEvent(object sender, TOnError args);
}
public class DummyEventHandler :
EventHandlerBase<NotificationEventArgs, DisconnectEventArgs, ErrorEventArgs>
{
public override void OnNotificationEvent(object sender, NotificationEventArgs args)
{
Console.WriteLine(MethodBase.GetCurrentMethod());
}
public override void OnDisconnectEvent(object sender, DisconnectEventArgs args)
{
Console.WriteLine(MethodBase.GetCurrentMethod());
}
public override void OnErrorEvent(object sender, ErrorEventArgs args)
{
Console.WriteLine(MethodBase.GetCurrentMethod());
}
}
public interface ISubscriber
{
void Subscribe();
void Unsubcribe();
}
public class DummyStreamingNotificationSubscriber : ISubscriber
{
private readonly IEventHandler<NotificationEventArgs, DisconnectEventArgs, ErrorEventArgs> _eventHandler;
public DummyStreamingNotificationSubscriber(
IEventHandler<NotificationEventArgs, DisconnectEventArgs, ErrorEventArgs> eventHandler)
{
_eventHandler = eventHandler;
}
public void Subscribe()
{
Console.WriteLine("Subscribing to streaming notification.");
var streamingConnection = new DummyStreamingSubscriptionConnection();
streamingConnection.OnNotification += _eventHandler.OnNotificationEvent;
streamingConnection.OnDisconnect += _eventHandler.OnDisconnectEvent;
streamingConnection.OnError += _eventHandler.OnErrorEvent;
}
public void Unsubcribe()
{
Console.WriteLine("Unsubscribing to streaming notification.");
}
}
// Only used to mimic EWS' StreamingSubscriptionConnection class
public class DummyStreamingSubscriptionConnection
{
public event EventHandler<NotificationEventArgs> OnNotification;
public event EventHandler<DisconnectEventArgs> OnDisconnect;
public event EventHandler<ErrorEventArgs> OnError;
}
// Mimics EWS' NotificationEventArgs class
public class NotificationEventArgs : EventArgs { }
// Mimics EWS' SubscriptionErrorEventArgs class
public class ErrorEventArgs : EventArgs { }
// Mimics EWS' SubscriptionErrorEventArgs class
public class DisconnectEventArgs : EventArgs { }
public class DummyService : IService
{
private readonly ISubscriber _subscriber;
public DummyService(ISubscriber subscriber)
{
_subscriber = subscriber;
}
public void Start()
{
Console.WriteLine("Starting service.");
_subscriber.Subscribe();
}
public void Stop()
{
Console.WriteLine("Stopping service.");
_subscriber.Unsubcribe();
}
}
И, наконец, склеиваем все это вместе.
var service = new DummyService(
new DummyStreamingNotificationSubscriber(
new DummyEventHandler()));
service.Start();
В классе ExchangeEventHandler
OnNotificationEvent()
будет получать электронную почту и работать с ней.Короче говоря, мне нужно иметь возможность заглушить (например, с помощью DI) обработку событий, чтобы гарантировать, что я все еще могу работать со своей службой потоковой подписки с или без Exchange.
Вопрос
Как я могупроверьте, что вызов события OnNotification
на самом деле вызовет соответствующий метод и сделает то, что должен (например, использует электронную почту).Я предполагаю, что насмешка придет в игру.По сути, я хочу убедиться, что после того, как будет реализована реальная реализация сервиса, когда однажды, например, событие OnNotification
сработает, оно действительно продолжит работу.
Пожалуйста, не стесняйтесь задавать вопрос, если что-тоне понятноЯ понимаю, что это может быть не идеальное решение, поэтому я также открыт для различных предложений по реализации.