Недавно у меня возникли проблемы с отображением событий из .NET в COM.
Я успешно справился с этим примером (концептуально взято из http://blogs.msdn.com/andreww/archive/2008/10/13/exposing-events-from-managed-add-in-objects.aspx):
// Тип делегата для нашего пользовательского события.
[ComVisible(false)]
public delegate void SomeEventHandler(object sender, EventArgs e);
// Outgoing (source/event) interface.
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IAddInEvents
{
[DispId(1)]
void SomeEvent(object sender, EventArgs e);
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(IAddInEvents))]
public class AddInUtilities :
{
// Event field. This is what a COM client will hook up
// their sink to.
public event SomeEventHandler SomeEvent;
inernal void FireEvent(object sender, EventArgs e)
{
if (SomeEvent != null)
{
SomeEvent(sender, e);
}
}
}
Это работает нормально, потому что интерфейс IAddInEvents определен как IDispatch . Однако мне нужно опубликовать интерфейс источника событий IUnknown . У меня нет контроля над интерфейсом событий, так как он поступает из сторонней библиотеки (которая также будет потребителем опубликованных событий). Всякий раз, когда я пытаюсь подключиться к событиям, происходит сбой среды VB (где я пытаюсь получить события), а также среда VBA, которую использует сторонний продукт (ESRI ArcMap).
Мне удалось (частично) реализовать интерфейс IConnectionPointContainer (который COM использует в фоновом режиме для обработки событий) вручную, затем я могу погрузить событие и войти в мою реализацию IConnectionPointContainer. Однако, это кажется мне излишним, и я думаю, что в .NET должна быть неявная поддержка этого. Во-вторых, при таком подходе я сразу теряю поддержку делегатов.
У кого-нибудь есть опыт с этим?
Заранее спасибо.