Event Aggregator: нужна помощь в изменении решения

Я пытаюсь разработать агрегатор событий для своего приложения. (Я новичок в шаблоне проектирования, поэтому я еще не до конца его понимаю).

Во-первых, я уже создал решение, которое в некоторой степени является агрегатором, но нуждается в улучшении и рефакторинге для достижения большей эффективности и уменьшения зависимостей.

1) В шаблоне разработки Event Aggregator мои источники данных.NET будут считаться издателями? (Я не уверен насчет роли издателей).

2) Как бы я разработал свое решение для обработки подписок не только на конкретные источники данных, но и на конкретные события данных, игнорируя при этом другие? Я хотел бы увидеть решение, которое отошло бы от ведения списков и неустанного их просмотра... но не уверен, смогу ли я избежать всего этого вместе.

2 ответа

Решение

Я думаю, что вы должны реализовать хорошего издателя / подписчика здесь. Мое предложение примерно так:

ваш издатель: EventAggregator должны иметь такие методы, как:

public void Register(IEventObserver observer, EventFilter filter)
public void Unregister(IEventObserver observer)

ваш IEventObserver должен выглядеть так

public interface IEventObserver
{
    void Notify(object eventSource, DetailedEventArgs e);
}

Ваши подписчики должны реализовать этот интерфейс.

ваш EventFilter Класс должен иметь все фильтрующие свойства, которые вы намереваетесь использовать. этот класс может иметь такой метод:

public bool IsSatisfiedBy(DetailedEventArgs e)

и создать класс Named DetailedEventArgs и унаследовать это от EventArgs, поместите все детали, которые вы хотите о событии на этом.

в Register Метод, вы должны хранить как фильтры, так и наблюдатели. теперь, когда ваш EventAggregator ловит событие, оно должно сначала создать DetailedEventArgs объект из полученного события, а затем зациклить наблюдателей и их фильтры, чтобы увидеть, удовлетворен ли фильтр объектом, и если это так, вызвать метод Notify наблюдателя с исходным отправителем и DetailedEventArgs объект.

Я настоятельно рекомендую вам проверить фильтр на стороне издателя, а не на стороне подписчика. потому что проверка на стороне подписчика сделает много кода дублирующимся и непоследовательным.

РЕДАКТИРОВАТЬ: пример EventFilter а также DetailedEventArgs классы:

public class EventFilter
{
    private List<Type> SourceTypes;
    private List<EventType> EventTypes;
    public EventFilter() : this(new Type[] { }, new EventType[] { }) { }
    public EventFilter(IEnumerable<Type> sourceTypes, IEnumerable<EventType> eventTypes)
    {
        SourceTypes = new List<Type>(sourceTypes);
        EventTypes = new List<EventType>(eventTypes);
    }
    public void AddSourceType(Type type)
    {
        AddItemToList(SourceTypes, type);
    }
    public void AddEventType(EventType type)
    {
        AddItemToList(EventTypes, type);
    }
    private void AddItemToList<T>(List<T> list, T item)
    {
        lock (list)
        {
            if (!list.Contains(item))
                list.Add(item);
        }
    }
    public bool IsSatisfiedBy(DetailedEventArgs args)
    {
        return SourceTypes.Contains(args.Source.GetType()) && EventTypes.Contains(args.EventType);
    }
}
public class DetailedEventArgs : EventArgs
{
    public EventArgs SourceArgs { get; private set; }
    public object Source { get; private set; }
    public EventType EventType { get; private set; }
    public DetailedEventArgs(object source, EventArgs sourceArgs, EventType eventType)
    {
        Source = source;
        SourceArgs = sourceArgs;
        EventType = eventType;
    }
}
public enum EventType
{
    EventType1,
    EventType2,
    EventType3
}

надеюсь я помог:)

Проверьте класс MVVM Light Messenger. Я основал свою реализацию на этом. Тем не менее, он использует списки и циклы, но я не вижу способа обойти это.

Я видел некоторые жалобы на утечку памяти, но это не повлияло на меня и может быть исправлено.

Другие вопросы по тегам