Контракт обратного вызова
У меня есть две стороны.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
, но это очень субъективно