Best way to implement bBrowser codeblocks in X#

This forum is meant for questions and discussions about the X# language and tools
ic2
Posts: 1858
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

Best way to implement bBrowser codeblocks in X#

Post by ic2 »

In the large program we are converting we use (in the end) a codeblock as parameter of add a bDataColumn like this:

Code: Select all

{|o|o:bBrowserMethod(8)}
This then calls a method of the class of the DBServer used in the call, e.g.

Code: Select all

METHOD BbrowserMethod(n) CLASS MyAddressDBServer
if n==8
  return self:Fieldget(#Phone)
endif

Not exactly the used code but it illustrates how we use it.

In VO we can freely have these methods anywhere in the program. In X# this won't work as it needs to reside in the same program where we define the specific dbServer class. And that is only possible if we add a reference to bBrowser libraries in library with DBServers which doesn't feel correct.

I thought I could solve this by creating a function like this:

Code: Select all

{||:bBrowserfunction(8,self:Server)}
Function bBrowserfunction(n,oServer)
// do something with the parameters and return a value



and wherever the current methods says something like self:Fieldget(#whatever) I could use oServer:Fieldget(#whatever) instead.

However, as soon as I put SELF in the parameter I get No self available although self is used within test of the calling method without problems.

What is the best way to solve this without including bBrowser library references in a library with dbservers?

Dick & Frank
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Best way to implement bBrowser codeblocks in X#

Post by wriedmann »

Hi Dick,
I don't know if the compiler option "all methods are virtual" changes something here.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
ic2
Posts: 1858
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

Best way to implement bBrowser codeblocks in X#

Post by ic2 »

Hello Wolfgang,

I am not sure what would change. According to Chris, in an earlier answer:

By default METHODs in .Net are not VIRTUAL, meaning that you cannot override a method of a base class by redefining it in a child class, like we do in VO, this instead creates a completely new method, from the CLR's point of view. In order to make a (base) method overrideable, you must explicitly mark it with the VIRTUAL keyword. Or, you can simply enable the "All instance methods virtual" project option, which tells the compiler to make all methods VIRTUAL by default, for compatibility with VO.

What I understand from this is that I can e.g. write a virtual method Skip() in a dbserver class doing something different than the default dbServer skip.

But I would say it does not mean that we can move these methods of the several dbserver classes, called by the codeblock, back to a more logical library with bBrowser included? I thought it was not possible in X# to create methods of a class in a library where the class isn't defined. regardless this setting?

Dick
User avatar
Chris
Posts: 4908
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Best way to implement bBrowser codeblocks in X#

Post by Chris »

Hi Dick,

I do not understand why you would need to add references to the bbRowser libraries in the DBServer libraries. Maybe you can explain more in depth the structure of your app and the problem itself?

.
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Best way to implement bBrowser codeblocks in X#

Post by wriedmann »

Hi Dick,
when you are using virtual methods, the bBrowser calls the correct method defined in your application, not a method that is defined in the standard DBServer class because it uses late binding.
Even in Core X# (and even C#) it is possible to call methods that are defined in the main executable from a library.
For me that is working.
Maybe I have to make a sample for you.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
FdeRaadt
Posts: 31
Joined: Wed Sep 01, 2021 12:49 pm
Location: Netherlands

Best way to implement bBrowser codeblocks in X#

Post by FdeRaadt »

Hi Wolfgang, Chris and more

Making the "all methods are virtual" does not change the end result.
We have a bBrowserfunction that essentially uses the FieldGet method of DBServer to return a logic.

Code: Select all

Class Contact_External_Class Inherit Contact
METHOD bBrowserFunction CLASS Contact_external_class
We've noticed the issue that our bBrowserfunction is never reached unless we place this method directly in the same project as where we define our DBServer Classes. I've tried making the Method virtual but nothing changes.

We would like to find a different approach due to the fact that most projects in our solution have a single responsibility. By moving this method to a Project that handles DBServer we're mixing responsibilities. This is something we're actively trying to avoid.

p.s Dont ask why me why our METHOD is called bBrowserfunction.

Frank
ic2
Posts: 1858
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

Best way to implement bBrowser codeblocks in X#

Post by ic2 »

I add to this, to answer Chris, one of the functions contains this code:

Code: Select all

	CASE n == 3   
		IF Left(SELF:FIELDGET(#SomeField),1) == "1"
			RETURN bCompoundValue{bIcon{OKKL{},16},,,BALIGN_RIGHT}
Because of bCompoundValue{, a bBrowser reference is required.

Also Frank posts Contact_external_class. This I think should be Contact (the name of one of the dbservers where this method should work on). It originally didn't work at all until I discovered that the class was changed to external_Class. We renamed it back to the original dbserver subclass contact, but that requires the method to be moved to the dbserver based library which, as Frank mentions, should not need bBrowser includes. But we can not move the codeblock called method to a more logical place without giving up the access to the dbServer which obviously is essential.

Dick
User avatar
Chris
Posts: 4908
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Best way to implement bBrowser codeblocks in X#

Post by Chris »

Guys,

Is this about the app of yours of which I already have the code for? If yes, can you please point me exactly to the part of the code that has this issue, so I can look into it directly and understand the problem? If not, can you create a sample demonstrating the problem? Please note that we have 40C here all day, so if I don't see the problem myself or get a very clear description, it's very unlikely that I will understand what's going on :)

.
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
User avatar
robert
Posts: 4520
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

Best way to implement bBrowser codeblocks in X#

Post by robert »

Frank
Have you considered making bBrowserFunction an extension method to the Contact class ?
The VOPad example in the X# help shows how to do that:
https://www.xsharp.eu/help/example-2-th ... ample.html

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Best way to implement bBrowser codeblocks in X#

Post by wriedmann »

Hi Dick,
ok, if I understand it correctly, you have defined the Contact:FieldGet() method in a different assembly than the one that contains the Contact class.
That will never work in X#, and I don't know if an extension method defined in the main library will be called by the bBrowser code. (@Robert: late binding uses extension methods?)
So, you could use the CreateInstance() function (or the relative Reflection method) and put your code into the library where the contact class is defined:

Code: Select all

IF Left(SELF:FIELDGET(#SomeField),1) == "1"
			RETURN CreateInstance( #bCompoundValue, bIcon{OKKL{},16},,,BALIGN_RIGHT)
That should definitely work.
Or, maybe you can do some other thing: subclass the Contacts class, define the FieldGet() method in the subclass and use the subclass instead of the Contacts class.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Post Reply