Translate some Visual Studio code - Forum - OpenEdge Development - Progress Community

Translate some Visual Studio code

 Forum

Translate some Visual Studio code

This question is not answered

Hi,

We need to replace some Visual studio code with Progress code but I have no idea how i need to translate the following:
ExtensionManager.Instance.Invoke(Of IPaymentHandlerExtension)(Sub(x) x.HandlePayment(paymentId, amount, comment))

Can someone give me a direction?

Regards
Didier

All Replies
  • I doubt that anyone on this forum know what "ExtensionManager.Instance.Invoke(Of IPaymentHandlerExtension)(Sub(x) x.HandlePayment(paymentId, amount, comment))” means.

    You will have to supply a lot more information about your environment before anyone will be able to assist.

    What OpenEdge version?

    Of what software is ExtensionManager a part?

    What are the datatypes being passed in the function call ?

    What are the expected return values?

  • DenDuze

    Hi,

    We need to replace some Visual studio code with Progress code but I have no idea how i need to translate the following:
    ExtensionManager.Instance.Invoke(Of IPaymentHandlerExtension)(Sub(x) x.HandlePayment(paymentId, amount, comment))

    Can someone give me a direction?

    Regards
    Didier

    Not so sure if ExtensionManager Invoke method is just the System.Reflection Invoke method, but here is a sample code to dynamically invoke a class method in ABL.

    DEFINE VARIABLE oMethod AS System.Reflection.MethodInfo NO-UNDO.
    DEFINE VARIABLE oType AS System.TYPE NO-UNDO.
    DEFINE VARIABLE bindingAttr AS BindingFlags NO-UNDO.
    DEFINE VARIABLE arrayVar AS System.Object EXTENT 2 NO-UNDO.

    bindingAttr = BindingFlags:Instance.
    bindingAttr = CAST(EnumHelper:Or(bindingAttr, BindingFlags:NonPublic), BindingFlags).
    oType = Progress.Util.TypeHelper:GetType("System.Windows.Forms.Control"). // IPaymentHandlerExtension
    oMethod = oType:GetMethod("RemovePendingMessages", bindingAttr). // HandlePayment

    IF VALID-OBJECT(oMethod) THEN
      oMethod:Invoke(THIS-OBJECT, arrayVar).

    THIS-OBJECT - is the object instance (x in your sample)
    arrayVar - parameters to method you are calling 

  • Hi Gus/jquerijero,

    The problem is that I also do not know what all this does.

    We need to put some existing functionality (currently written in vb) in our Progress application.

    The person who implemented that functionality only executed ths following code:

    ' Handle payments

    If RadioButtonShop.Checked = True Then

        For Each row As DataGridViewRow In DataGridViewInvoicePayments.Rows

             Dim amount = cVerGeneralSubsAndFunctions.ReturnSingleIfNull(DataGridViewInvoicePayments("PaymentAmount", row.Index).Value)

              If amount < 0.01 Then Continue For

                   Dim comment = String.Format("{0}-{1}/{2}", TextBoxDocumentNumber.Text, VERPigoMainForm.strBranchCode, Strings.Right(MaskedTextBoxCustomerNumber.Text, VERPigoMainForm.intLengthCustomerNumber))

             Dim paymentId = CInt(row.Cells("PaymentMethodID").Value)

                   ExtensionManager.Instance.Invoke(Of IPaymentHandlerExtension)(Sub(x) x.HandlePayment(paymentId, amount, comment))

       Next

    End If

    He tells me that when he calls that ExtensionManager:instance:Invoke a form is shown where the user can make some payments.

    So the easiest way for me to implement that functionality is try to do the same but I have no idea what that line of code just does (I'm no .net programmer, I understand a bit but ...)

    If needed I can provide you the ExtentionManager.vb file but maybe the comment on top of that file can help

    This class will scan a directory for dll's with types that implement IExtension

    'Any types found are instanciated and available to call using the ExtensionMethod.Invoke(Of T) method

    The Invoke method has the following code:

    Public Sub Invoke(Of T)(act As Action(Of T))

     For Each extension As IExtension In _extensions.Where(Function(e) GetType(t).IsAssignableFrom(e.GetType))

          Dim extOfT = DirectCast(extension, T)

          act(extOfT)

       Next

    End Sub

    The IPaymentHandlerExtension has the following code:

    Public Interface IPaymentHandlerExtension

       Inherits IExtension

       Function HandlePayment(paymentMethodId As Integer, amount As Single, comment As String) As Boolean

    End Interface

    There is also a class AdyenPaymentHandlerExtension that Implemants the iPaymentHandlerExtension where the HandlePayment method is implemented

    For the rest there are some other files but as far as I know (hope) I do not need to know what these do because when I could replace that

    ExtensionManager.Instance.Invoke(Of IPaymentHandlerExtension)(Sub(x) x.HandlePayment(paymentId, amount, comment))

    It should hopefully work (that's what that person who made the vb-code said)

    regards

    Didier

  • VB.NET … not my speciality.
     
    But if I recall right, the (Of IPaymentHandlerExtension) is the VB.NET syntax for generic methods.
     
    If that’s the case, you’ll need to use reflection as the ABL does not support accessing .NET generic methods (on non generic types).
     
     

    Architect of the SmartComponent Library and WinKit

    Consultingwerk Ltd.

  • Hi Mike,

    I can only see a Telerik.WinControls.ReflectionHelper in the Class Browser.

    I guess that one is only for Telerik controls.

    In my case it's not a Telerik controls so ....

    Regards

    Didier

  • That ReflectionHelper is an ABL class. Source code is in the Github repo.

    Architect of the SmartComponent Library and WinKit

    Consultingwerk Ltd.

  • @Mike: ok but i guess that belongs to the consulting SmartComponent framework so i can't use that - or I'm I wrong about that? I never used something like this .

    @jquerijero: I also tried your approch but the oMethod is not a valid-object so I must do something wrong here.

    I used the following code to test:

    define variable oMethod as System.Reflection.MethodInfo no-undo.

    define variable oType as System.Type no-undo.

    define variable bindingAttr as System.Reflection.BindingFlags no-undo.

    define variable arrayVar as System.Object extent 3 no-undo.

    bindingAttr = System.Reflection.BindingFlags:Instance.

    bindingAttr = CAST(Progress.Util.EnumHelper:or(bindingAttr, System.Reflection.BindingFlags:NonPublic), System.Reflection.BindingFlags).

    oType = Progress.Util.TypeHelper:GetType("Verpigo.Extensibility.IPaymentHandlerExtension").

    /* here both object are valid */

    message program-name(1) skip valid-object(oType) skip valid-object(bindingAttr)

    view-as alert-box.

    oMethod = oType:GetMethod("HandlePayment", bindingAttr). // HandlePayment

    /* this gives me false back whle the function is defined there like

    Function HandlePayment(paymentMethodId As Integer, amount As Single, comment As String) As Boolean */

    message program-name(1) skip 'omethod ' valid-object(oMethod)

    view-as alert-box.

    regards

    Didier

  • The bits on Github are released under the MIT license.

    Architect of the SmartComponent Library and WinKit

    Consultingwerk Ltd.

  • ok, tried it with that but It's unclear to me how I need to use that in my case

    I tried the following method PUBLIC System.Object InvokeGenericMethod (Object, character, character)

    def var o as Verpigo.Extensibility.ExtensionManager.

    def var o2 as PaymentExtension_Adyen.AdyenPaymentHandlerExtension.

    o2 = CAST (ReflectionHelper:InvokeGenericMethod(o,

                                                                                            "HandlePayment",

                                                                                           "Verpigo.Extensibility.ExtensionManager").

    But I get error 205

    I'm sure I'm doing something wrong (but that's normal because I have no idea what this does)

    The code to translate is:

    ExtensionManager.Instance.Invoke(Of IPaymentHandlerExtension)(Sub(x) x.HandlePayment(paymentId, amount, comment))

    Please advise

  • For those of us, that don’t know 18000 Progress error messages by heard, what is 205?
     
    But your CAST is missing the second argument, the target type:
     

    o2 = CAST (ReflectionHelper:InvokeGenericMethod(o,

                                                                                            "HandlePayment",

                                                                                           "Verpigo.Extensibility.ExtensionManager"),

          PaymentExtension_Adyen.AdyenPaymentHandlerExtension) .

     
     

    Architect of the SmartComponent Library and WinKit

    Consultingwerk Ltd.

  • Arrrrh, damn how stupid.

    Changed it but I get

    Invalid handle.  Not initialized or points to deleted object (3135)

    I also tried with

    o2 = CAST (ReflectionHelper:InvokeGenericMethod( o,

                                                    "Invoke",

                                                    "Verpigo.Extensibility.ExtensionManager"),

                                                    PaymentExtension_Adyen.AdyenPaymentHandlerExtension).

    But then I get

    System.Reflection.TargetParameterCountException: Parameter count mismatch.

    Like I already mentioned it's not clear to me what the original code just does:

    ExtensionManager.Instance.Invoke(Of IPaymentHandlerExtension)(Sub(x) x.HandlePayment(paymentId, amount, comment)).

    Maybe someone can explain me what this code just does because I tried multiple things but always get some kind of error

    The Invoke methos in ExtensionManager.vb:

    Public Sub Invoke(Of T)(act As Action(Of T))

           For Each extension As IExtension In _extensions.Where(Function(e) GetType(t).IsAssignableFrom(e.GetType))

               Dim extOfT = DirectCast(extension, T)

               act(extOfT)

           Next

       End Sub

    The HandlePayment method in AdyenPaymentHandlerExtension;vb:

    Public Function HandlePayment(paymentMethodId As Integer, amount As Single, comment As String) As Boolean Implements IPaymentHandlerExtension.HandlePayment

           'only handle the payment codes that are configured in the config file

           If Not AcceptedPaymentMethodIds.Contains(paymentMethodId) Then

           Return False

           End If

           Parameters = New List(Of String) From {"-a", amount.ToString(CultureInfo.InvariantCulture), "-c", comment}

           Return RunProcess() = 0 'external process has to return 0 if everything is OK

       End Function

    So I really have no idea it that is translatable  to Progress or not (and how)

  • Is o initialized  ?

    Architect of the SmartComponent Library and WinKit

    Consultingwerk Ltd.

  • I guess it is,

    I did:

    def var o as Verpigo.Extensibility.ExtensionManager.

    Verpigo.Extensibility.ExtensionManager:Init("C:\Users\didier.d\Desktop\test_angloParts").

    o = Verpigo.Extensibility.ExtensionManager:Instance.

    When I do valid-object(o) I get true back so...

    Regards

    Didier

  • As I said before. VB.NET ... what I'd suggest is that you share the link to the API documentation of the classes you're trying to access.

    Architect of the SmartComponent Library and WinKit

    Consultingwerk Ltd.

  • Now understand, Invoke is actually trying to call HandlePayment on all available matching extensions. I don't think this is translatable to ABL. The code I posted will not work; it's for a different purpose.

    Specially this line will not translate:
    ExtensionManager.Instance.Invoke(Of IPaymentHandlerExtension)(Sub(x) x.HandlePayment(paymentId, amount, comment)) because Sub(x) x.HandlePayment(paymentId, amount, comment) is an inline delegate definition.

    The key is re-implementing Invoke to not use delegate. Basically, Invoke should look something like this;

    Invoke(paymentId, amount, comment)
    ... You might need to iterate through all the extension and see which extension implements HandlePayment by checking if TYPE-OF is IPaymentHandlerExtension.