VB.Net System.Action(Of T) help needed

Wizard's Enterprise 1 Reputation point
2021-05-21T20:25:27.81+00:00

Hello,

This is my first time working with System.Action(Of T) and I'm having an extremely difficult time doing something that I'm sure is very simple to the other experienced people here and I am hoping that someone can help me with a solution.

Background: I am trying to utilize a DLL given to me by a third party in my own DLL that I am creating. Basically I am trying to create a "wrapper" so that the things that my DLL can be referenced in other projects and I can access the third party DLL through my DLL in ways that are easier for me and more streamlined for my use. I want to create a DLL that references another DLL; The projects that reference my DLL will be using my DLL to access the services of the third party DLL without directly interacting with the third part DLL at all.

Identifiers: My DLL is called WizCrypto, and the third party DLL is called Binance.Net

Problem: So Binance.Net DLL has a websocket that I can connect to and make a call to be notified any time there is a trade on a specific coin. In order to subscribe to this update I have to pass in a function because the parameter is a System.Action. The Binance.Net function I need to use to subscribe to these trade updates is

SubscribeToTradeUpdates(symbol As String, onMessage As Action(Of BinanceStreamTrade))

I have created a subroutine like this in my DLL as the onMessage callback function:

Private Sub NewTradeNotification(tradeData as BinanceStreamTrade)
     'Do some kind of action here with the tradeData object
End Sub

So in my DLL, when I call the Binance.Net function to subscribe to updates I pass in the address of my callback function:

Private Function GetLiveTradeUpdates(strSymbol As String) As CryptoExchange.Net.Objects.CallResult(Of CryptoExchange.Net.Sockets.UpdateSubscription)
     Dim objTradeSubscription As CryptoExchange.Net.Objects.CallResult(Of CryptoExchange.Net.Sockets.UpdateSubscription)
     objTradeSubscription = BinanceSocketClient.Spot.SubscribeToTradeUpdates(strSymbol, AddressOf NewTradeNotification)
     Return objTradeSubscription
End Function

This works fine inside of my DLL and it will call my callbackfunction anytime there is a trade on the symbol provided. The problem is that I can't figure out how to make this accessible OUTSIDE of my DLL to a project that is referencing my DLL. Keep in my that I don't want projects that reference my DLL to have to make any type of references to the Binance.Net DLL for parameters or anything, I want to mask that all so that everything appears to be from WizCrypto.DLL.

So for step one I made a new Public GetLiveTradeUpdates method that can be called and the user can pass in the address of a callback function for the notifications.

Public Sub GetLiveTradeUpdates(strSymbol As String, CallbackFunction As Action(Of MARKETSTREAM.BinanceStreamTrade))
    Dim objUpdateSubscription As CryptoExchange.Net.Objects.CallResult(Of CryptoExchange.Net.Sockets.UpdateSubscription)
    objUpdateSubscription = _SocketClient.Spot.SubscribeToTradeUpdates(strSymbol, CallbackFunction)
End Sub

And the user calls it like this and it works, their subroutine is called by the subscription in my DLL.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim CryptoTrader As New WizCrypto.BinCli("589057096")
    Dim bSuccess As Boolean = False
    bSuccess = CryptoTrader.GetLiveTradeUpdates("BTCUSDT", AddressOf HandleTradeNotification)
    If Not bSuccess Then
        MsgBox("There was an unknown error")
    End If
End Sub

Private Sub HandleTradeNotification(tradeData As Binance.Net.Objects.Spot.MarketStream.BinanceStreamTrade)
    MsgBox(tradeData.Price)
End Sub

The problem is that the user has to have a reference to the Binance.Net DLL in order to call my CryptoTrader.GetLiveTradeUpdates function because it requires the address of a function with a signature that requires a parameter of the type Binance.Net.Objects.Spot.MarketStream.BinanceStreamTrade. I wasn't sure how to get around this and so I found something called Inherits. In my DLL I modified things by creating a class to mimic the BinanceStreamTrade called WizCryptoStreamTrade and inherited the BinanceStreamTrade. Then I changed the Action of BinanceStreamTrade to my new object that inherits it so it looks like this:

Public Function GetLiveTradeUpdates(strSymbol As String, CallbackFunction As Action(Of WizCryptoStreamTrade)) As Boolean
    Dim objUpdateSubscription As CryptoExchange.Net.Objects.CallResult(Of CryptoExchange.Net.Sockets.UpdateSubscription)
    objUpdateSubscription = _SocketClient.Spot.SubscribeToTradeUpdates(strSymbol, CallbackFunction)
    Return objUpdateSubscription.Success
End Function

Public Class WizCryptoStreamTrade
    Inherits Binance.Net.Objects.Spot.MarketStream.BinanceStreamTrade
    Sub New()
        MyBase.New
    End Sub
End Class

And now the client will call it like this, without having to reference Binance.Net

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim CryptoTrader As New WizCrypto.BinCli("589057096")
    Dim bSuccess As Boolean = False
    bSuccess = CryptoTrader.GetLiveTradeUpdates("BTCUSDT", AddressOf HandleTradeNotification)
    If Not bSuccess Then
        MsgBox("There was an unknown error")
    End If
End Sub

Private Sub HandleTradeNotification(tradeData As WizCrypto.BinCli.WizCryptoStreamTrade)
    MsgBox(tradeData.Price)
End Sub

PROBLEM: But now my DLL throws an error when calling the Binance.Net's SubscribeToTradeUpdates because it is expecting me to pass in a callback function that has a parameter signature of BinanceStreamTrade but I am passing in a callback function with a parameter signature of WizCryptoStreamTrade. I tried googling and came across things like Delegate, etc... but I've gotten really confused and nothing I am trying is working to resolve this issue. Binance.Net is expecting a parameter of System.Action(Of BinanceStreamTrade) and I'm trying to pass in System.Action(Of WizCryptoStreamTrade). I thought that by inheriting the BinanceStreamTrade it would make the signature match even though the name of the type doesn't, but that didn't work. Then I tried to see if there was some way that I could let the user pass System.Action(Of WizCryptoStreamTrade) to my DLL and then my DLL convert that to System.Action(Of BinanceStreamTrade) so that it can call the Binance.Net function, but I can't figure out a way to do that either. What is the easiest way to solve this, because I will also need to do this again with other parameters.

Thank you so much for your help, I really have exhausted myself trying to figure this out myself before posting for help.

VB
VB
An object-oriented programming language developed by Microsoft that is implemented on the .NET Framework. Previously known as Visual Basic .NET.
2,668 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Viorel 114.7K Reputation points
    2021-05-22T08:36:26.997+00:00

    If you want to avoid references to Binance.Net, and BinanceStreamTrade is a relatively simple class, then define a new WizCryptoStreamTrade class that does not inherit from BinanceStreamTrade, but contains similar properties (the required ones only), which will be copied from BinanceStreamTrade. Something like this:

    Public Function GetLiveTradeUpdates(strSymbol As String, CallbackFunction As Action(Of WizCryptoStreamTrade)) As Boolean
        . . .
        a = CallbackFunction
        objUpdateSubscription = _SocketClient.Spot.SubscribeToTradeUpdates(strSymbol, NewTradeNotification)
        Return objUpdateSubscription.Success
    End Function
    
    Private a as Action(Of WizCryptoStreamTrade)
    
    Private Sub NewTradeNotification(tradeData as BinanceStreamTrade)
        Dim d as New WizCryptoStreamTrade
    
        ' copy data from ‘tradeData’ to ‘d’
        ' example: d.Amount = tradeData.Amount
        . . .
    
        ' notify the client
        a( d )
     End Sub
    
    0 comments No comments