Search code examples
vb.netroslyndataadapterdevart

Cannot bind to event via reflection on VS2015


I've a piece of code that fills a database table from a DataTable using a DbDataAdapter.

The DbDataAdapter is created via DbProviderFactory.CreateDataAdapter method, where DbProviderFactory is provided by Devart dotConnect.
We use Devart's drivers for Oracle, SqlServer and Postgres.

Since I have nearly 100k rows in my DataTable, I need to bind to the RowUpdated event (to update a progress bar) which unfortunately is not defined on a common interface, despite it is available in all the mentioned database drivers.

Therefore I bind it via reflection with this code:

Dim eventInfo As System.Reflection.EventInfo = adapter.GetType().GetEvent("RowUpdated")
eventInfo.AddEventHandler(adapter, [Delegate].CreateDelegate(eventInfo.EventHandlerType,
                          (Sub(s As Object, e As EventArgs) UpdateProgress(s, e)).Method))

This perfectly works if compiled with VS2013, but fails at runtime if compiled on Roslyn (VS2015), with this exception:

Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type

Any help on this?

Neither using Devart.Data.PostgreSql.PgSqlRowUpdatedEventHandler (I'm currently on Postgres) as the type of e works.


Solution

  • Starting from this answer posted in a comment by @djv, I finally get to the culprit.

    It seems that, with Roslyn (VS2015), you need to explicitly declare the Delegate prior to binding the event handler.

    For example, in my case, I need to write:

    Public Delegate Sub RowUpdatedEventHandler(sender As Object, e As RowUpdatedEventArgs)
    

    And then:

    Dim eventInfo As System.Reflection.EventInfo = adpt.GetType().GetEvent("RowUpdated")
    eventInfo.AddEventHandler(adpt, [Delegate].CreateDelegate(eventInfo.EventHandlerType,
                              DirectCast(AddressOf UpdateProgress, RowUpdatedEventHandler).Method))
    

    Also it seems it has some issues with lamdas. For example, this DOES NOT WORK:

    Dim eventInfo As System.Reflection.EventInfo = adpt.GetType().GetEvent("RowUpdated")
    eventInfo.AddEventHandler(adpt, [Delegate].CreateDelegate(eventInfo.EventHandlerType,
                              DirectCast((Sub(s As Object, e As RowUpdatedEventArgs) UpdateProgress(s, e)), RowUpdatedEventHandler).Method))
    

    (with or without DirectCast on the lambda expression)