Контракт обратного вызова

У меня есть две стороны.NET, которые должны быть связаны контрактом. Теперь party1 и party2 должны иметь возможность вызывать некоторые методы друг у друга (большинство из них - это вызовы и возвращение результатов). Я имею в виду дуплексный контракт, но стороны не используют WCF.

Есть ли шаблон дизайна для этого?

редактировать

Стороны являются частью одного приложения. Я создаю приложение (party1), а кто-то еще создает dll (party2), который я загружаю динамически. Теперь мы оба должны иметь возможность вызывать методы друг для друга. Итак, я собираюсь создать интерфейсный контракт между нами. Намерение состоит в том, чтобы узнать, существует ли шаблон для этого?

2 ответа

Решение

Распространенным решением является использование какого-либо паттерна pub/sub. Тем самым вы можете избежать циклических зависимостей.

По сути, вы создаете какой-то класс, который используется для подписки на события (и их публикации).

Так что оба ваших класса делают что-то вроде этого (но с разными событиями):

public class ClassA : IEventHandler<UserCreated>
{
    IEventManager _eventManager

    public ClassA(IEventManager manager)
    {
       // I subscribe on this event (which is published by the other class)
       manager.Subscribe<UserCreated>(this);
       _eventManager = manager;
    } 

    public void Handle(UserCreated theEvent)
    {
        //gets invoked when the event is published by the other class
    }

    private void SomeInternalMethod()
    {
        //some business logic

        //and I publish this event
        _eventManager.Publish(new EmailSent(someFields));
    }
}

Менеджер событий (упрощенный и не потокобезопасный):

public class EventManager
{
    List<Subscriber> _subscribers = new List<Subscriber>();

    public void Subscribe<T>(IEventHandler<T> subscriber)
    {
        _subscribers.Add(new Subscriber{ EventType = typeof(T), Subscriber = subscriber});
    }

    public void Publish<T>(T theEvent)
    {
        foreach (var wrapper in subscribers.Where(x => x == typeof(theEvent)))
        {
            ((IEventHandler<T>)wrapper.Subscriber).Handle(theEvent);
        }
    }
}

Маленькая обертка:

public class Subscriber
{
    public Type EventType;
    public object Subscriber;
}

Вуаля. два класса теперь слабо связаны друг с другом (все еще будучи в состоянии общаться друг с другом)


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

public class EventManager
{
    IYourContainer _container;

    public EventManager(IYourContainer container)
    {
        _container = container;
    }

    public void Publish<T>(T theEvent)
    {
        foreach (var subscriber in _container.ResolveAll<IEventHandler<T>>())
        {
            subscriber.Handle(theEvent);
        }
    }
}

Я думаю, что вы можете использовать следующую логику:

 Class1: Interface1 , Class2:Interface2, 

class Manager{
   public Manager(Interface1 managedPart1,Interface2 managedPart2){
        ... some logic for connect to interfaces
   }

}

Этот способ напоминает мне шаблон Bridge, но это очень субъективно

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