Page 7 of 8
New to X# and need some direction
Posted: Wed Jun 27, 2018 7:03 am
by wriedmann
Hi Tom,
as far as I remember, some months ago the development team allowed to use also the dot instead of the colon.
But personally I prefer to use the dot where applicable to have more readable code (IMHO one of the biggest advantages of the xBase language).
Wolfgang
P.S. you had a personal crash course into X# and .NET the last days <g>
New to X# and need some direction
Posted: Wed Jun 27, 2018 7:28 am
by lumberjack
Hi Tom,
Great news!!! Glad you have it sorted. Now for the hard part. You need to create a Singleton class to put this in....
A singleton class is a class that can only have 1 instance in an application. You don't want to make all the interface calls repeatedly in your application. You need to do it once and consume it many times.
tom@dieselworks.com.au wrote:
First hurdle done
So off you go and do some hard work
Code: Select all
CLASS MYOB
STATIC HIDDEN _inst AS MYOB //Note this, the placeholder for the object
HIDDEN oConfig AS ApiConfiguration
HIDDEN oCFService AS CompanyFileService
HIDDEN oCOFileList AS //oCFService:GetRange() Check what the type is that GetRange returns
HIDDEN sStatusText AS STRING
HIDDEN oCOFile AS Version
HIDDEN oCredentials AS CompanyFileCredentials
HIDDEN oAccService AS AccountService
HIDDEN oAccList AS //oAccService:GetRange(oCOFile,NULL,oCredentials,NULL) Check type of GetRange
STATIC CONSTRUCTOR()
_inst := MYOB{} // This creates the single instance of MYOB in your application.
RETURN
HIDDEN CONSTRUCTOR() // This will be automatically called by the STATIC CONSTRUCTOR.
SELF:InitializeMYOB()
RETURN
HIDDEN InitializeMYOB() AS VOID
SELF:oConfig := ApiConfiguration{"http://localhost:8080/accountright"}
SELF:oCFService := CompanyFileService{oConfig}
SELF:oCOFileList := oCFService:GetRange()
SELF:sStatusText := "Company Files set"
SELF:oCOFile := oCOFileList.FirstOrDefault({x => Version{x:ProductVersion} >= Version{"2013.3"}})
SELF:oCredentials := CompanyFileCredentials{"Administrator","xxxxxxxxxxx"}
SELF:oAccService := AccountService{oConfig}
SELF:oAccList := oAccService:GetRange(oCOFile,NULL,oCredentials,NULL)
RETURN
STATIC PROPERTY Inst AS MYOB // To access the MYOB object
GET
RETURN _inst
END GET
END PROPERTY
//This you need to extend to include all hidden Properties of the class you need to expose.
//I will do the StatusText. Just copy and paste and change <Name>, <Type> and what to RETURN.
PROPERTY Status AS STRING
GET
RETURN SELF:sStatusText
END GET
END PROPERTY
END CLASS
//Where you need the MYOB class in your app
VAR oMYOB := MYOB.Inst // Note NEVER MYOB{}
//or
LOCAL oMYOB AS MYOB
oMYOB := MYOB.Inst // Always .Inst It is a static property of the class not a property of the object
// Note in both cases NEVER MYOB{} since the class will do it automatically first time you access it.
// Your only way of getting the object is by use of MYOB.Inst
oMYOB:Status
Hope you learned a new trick of the .NET world!!!
Regards,
New to X# and need some direction
Posted: Wed Jun 27, 2018 7:43 am
by NickFriend
Hi Johan,
Just out of interest, why choose a singleton class over a static one? In the few cases where they're needed I've always gone with static classes, but I'd be interested to hear the logic of using singletons instead.
Thanks
Nick
New to X# and need some direction
Posted: Wed Jun 27, 2018 7:52 am
by wriedmann
Hi Nick,
that was my proposal... So Johan may be innocent....
I'm using this because it works well for me as central configuration object. But I make the single instance never available, only the relative properties.
Wolfgang
New to X# and need some direction
Posted: Wed Jun 27, 2018 8:39 am
by lumberjack
Hi Nick,
NickFriend wrote:
Just out of interest, why choose a singleton class over a static one? In the few cases where they're needed I've always gone with static classes, but I'd be interested to hear the logic of using singletons instead.
Good question
Next one?
Well my understanding of a static class is that you can never create an object of it. I know Vulcan had a bug that allowed you to actually create an object from it. Have not tested it with X# though...
A singleton force only 1 instance of the class to exist. Like in Tom's MYOB case, you cannot mix and match different company's data in the same session. I know my example is to an extend "hard coded". but I will extend the class a bit to accept setting of the properties e.g.:
Code: Select all
PROPERTY Config AS STRING
STATIC LOCAL lIsSet AS LOGIC
GET
IF lIsSet
RETURN SELF:sConfig
ENDIF
THROW Exception{"Configuration not set"}
END GET
SET
IF lIsSet
THROW Exception{"Configuration already set"}
ENDIF
SELF:sConfig := VALUE
SELF:oConfig := ApiConfiguration{VALUE}
lIsSet := TRUE
END SET
END PROPERTY
If you can show me how you do the above with a static class, I will reconsider my answer, accept both as equally feasible or static as better.
@Wolfgang: No was already thinking of a Singleton when Tom posted his original question. You beat me to the suggestion.
Hope this answer your question,
Hope this explains.
New to X# and need some direction
Posted: Wed Jun 27, 2018 9:03 am
by tom@dieselworks.com.au
Hi Johan, thanks for this, yes looks like I am learning something new again. Can you confirm this is what I think I see:
The MYOB Object is much like a Global Hidden class instance that we can access through functions but no direct referencing except since X# is fully OO, we have no functions..... this is why I could not find them
New to X# and need some direction
Posted: Wed Jun 27, 2018 9:22 am
by NickFriend
As ever, apologies for the C#!
Unless I'm missing something.....
Code: Select all
private static bool IsSet;
private static string sConfig;
public static string Config
{
get
{
if (IsSet)
return sConfig;
else
.......
}
set
{
if (IsSet)
.......
sConfig = value;
.....
IsSet = true;
}
}
I've seen long discussions about the singleton pattern vs static, but never seen anything that swings it one way or the other. Statics always seem easier as you don't need to instantiate them yourself (it's done automatically at program start).
Hence my curiosity... always interested to improve my coding style.
Nick
New to X# and need some direction
Posted: Wed Jun 27, 2018 9:29 am
by robert
Nick,
Singletons are stored in the Heap. Static fields in a static class are on the Stack afaik.
You are also able to control when the Singleton gets created and it can implement interfaces. Also you can inherit from a singleton class.
From stack overflow:
Static Class:
- You cannot create the instance of static class.
- Loaded automatically by the .NET Framework common language runtime (CLR) when the program or namespace containing the class is loaded.
- We cannot pass the static class to method.
- We cannot inherit Static class to another Static class in C#.
- A class having all static methods.
- Better performance (static methods are bound at compile time)
Singleton:
- You can create one instance of the object and reuse it.
- Singleton instance is created for the first time when the user requested.
- You can create the object of singleton class and pass it to method.
- Singleton class does not say any restriction of Inheritance.
- We can dispose the objects of a singleton class but not of static class.
- Methods can be overridden.
- Can be lazy loaded when need (static classes are always loaded).
- We can implement interface(static class can not implement interface).
Robert
New to X# and need some direction
Posted: Wed Jun 27, 2018 10:32 am
by lumberjack
Hi Nick,
I do understand c# so not a problem
However, I think it starts looking a lot more manageable when we have 2 properties to do. Forgive my X#
Code: Select all
PROPERTY Config1 AS STRING
STATIC LOCAL lIsSet AS LOGIC
// This is as far as I know only a VO/Vulcan/X# feature.
// Keep the value of lIsSet even if out of scope.
GET
....
END GET
SET
....
END SET
END PROPERTY
PROPERTY Config2 AS STRING
STATIC LOCAL lIsSet AS LOGIC
GET
...
END GET
SET
....
END SET
END PROPERTY
I've seen long discussions about the singleton pattern vs static, but never seen anything that swings it one way or the other. Statics always seem easier as you don't need to instantiate them yourself (it's done automatically at program start).
Well you also don't need to instantiate Singletons, it will be done first time you access it.
Voila instantiated, if I never do this, it will never reside in memory. So bad programming don't eat up resources.
The beauty of the pre-processor in VO/X# also comes into play, I hate writing all that code to check lIsSet, hence:
Code: Select all
#command FORCE SET PROPERTY <p> AS <t> GETSET <i> => ....
#command FORCE SINGLE SET PROPERTY <p> AS <t> GETSET <i> => ....
And voila now all I have to do is:
Code: Select all
FORCE SET PROPERTY Config1 AS STRING GETSET oConfig1
FORCE SINGLE SET PROPERTY Config2 AS STRING GETSET oConfig2
Ok if that does not motivate you to drop using static c# (no pun intended), you can continue to use static classes...
Happy static[ing] along
,
New to X# and need some direction
Posted: Wed Jun 27, 2018 10:52 am
by wriedmann
Hi Johan,
for properties I prefer the short syntax. Instead of
Code: Select all
property MyProp as string
get
return _cMyProp
end get
set
_cMyProp := value
end set
end property
you can write
Code: Select all
property MyProp as string get _cMyProp set _cMyProp := value
Wolfgang