Общим решением является использование своего рода паба/подпрограммы. Поступая таким образом, вы можете избежать круговых зависимостей.
В основном вы создаете класс, который используется для подписки на события (и публикует их).
Так как ваши классы делает что-то вроде этого (но с разными событиями):
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;
}
Voila. два класса теперь слабо связан друг с другом (в то время как еще в состоянии общаться друг с другом)
Если вы используете инверсию управления контейнером его получить легче, так как вы можете упростить менеджер событий и просто использовать контейнер (место службы) для решения всех абонентов:
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);
}
}
}
Если они не используют WCF, как они общаются? Это то, что обычно обрабатывается стеком службы, который поддерживает сеансы. – millimoose
Являются ли части, которые просто кодируют разные части одного приложения, вызывая непосредственно сборки друг друга? Если это так, интерфейсы (или абстрактные классы) + кодовые контракты (см. Http://msdn.microsoft.com/en-us/library/dd264808.aspx) могут быть хорошим способом пойти –
Кроме того, «классический» шаблон дизайна может использоваться инъекция зависимостей (http://martinfowler.com/articles/injection.html). Но на самом деле, без дополнительной информации и контекста, трудно сказать ... –