Expondo eventos de .NET para COM
Pergunta
Recentemente, tenho encontrado problemas com a exposição de eventos de .NET para COM.
Tive sucesso com este exemplo (conceitualmente retirado de http://blogs.msdn.com/andreww/archive/2008/10/13/exposing-events-from-managed-add-in-objects.aspx):
// O tipo de delegado para o nosso evento personalizado.
[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);
}
}
}
Isso funciona bem, porque a interface iaddinevents é definida como Idispatch. No entanto, eu preciso Publique uma interface de fonte de evento que é iunknown. Não tenho controle sobre a interface do evento, pois vem de uma biblioteca de terceiros (que também será o consumidor dos eventos publicados). Sempre que tento conectar os eventos, o ambiente VB (onde estou tentando afundar os eventos) trava, o mesmo acontece com o ambiente VBA que o produto de terceiros (ESRI Arcmap) usa.
Eu consegui (parcialmente) implementar ICONNECTION PontoContainer Interface (que o COM usa em segundo plano para lidar com eventos) manualmente, então sou capaz de afundar o evento e entrar na minha implementação do ICONNECTION PointContainer. No entanto, isso parece um exagero para mim e acho que deve haver um apoio implícito para isso no .NET. Segundo, com essa abordagem, perca instantaneamente o apoio do delegado.
Alguém tem alguma experiência com isto? Desde já, obrigado.
Solução 2
OK, então eu consegui implementar o clássico Comb IconnectionPointCointainer, ICONNECTION e ICONNENCION (mais as interfaces de enumeração). Ele não se integra ao modelo de delegado/evento .NET, mas funciona.
Outras dicas
Simplesmente, você não poderá fazer isso. O VB clássico não suporta não automação (como você viu).
Você precisará ter um invólucro que possa passar em sua instância de automação para qual publicará o evento de não automação. Você efetivamente terá que ter dois tipos separados para lidar com os dois clientes separados para os eventos (habilitada por automação e não automaticamente ativada).