Running code if class exists

Im writing a set of reusable components . I want to enable optional functionality only if a given component is implemented, without having explicitly wire them together in code (ie calling an initializing function, factory, etc).

I want to run a particular code only if a class exists (by class name).

For example: If I add to the project a class with a given name I want other parts of the code to do something with that class.

(I want things to sort of magically talk to each other, without forcing to use a particular subclass.)

So far the only way I see is to walk the runtime.IterateObjects.

PS: I already have a controller/messaging implementation used for interpolation without forcing to use a particular subclass.

Wouldn’t delegates work in your case?

This is an area where Xojo’s strength becomes a weakness. At some point in the code, that class name must be typed. What you want to do is mostly impossible, but I do have an idea if the list of all possible classes is known at compile time.

You could add a constant for each class to some module. Something like ClassAExists = True, ClassBExists = False, and so on. Then you would use a build script to check if each of these project items exist, and set the constant accordingly. Your code could wrap sections in #if ClassAExists blocks to enable or disable features.

You’d still run into trouble if you needed properties that reference these types, as you can’t set them to require certain constant values without mucking with the text format by hand, something I strongly advise against.

This is an uphill battle for sure.

1 Like

Why don’t you create your reusable components as external console apps, so you can launch them from your main app? (if the module is not present nothing will happen)
Then if you need your processes to talk you can connect rhem with an IPC socket.

I already asked for this a loooooong time ago, and some people of the xojo team told me at the time this was not possible. may be it has changed but I don’t think so.

No, that’s still true. My idea is a hack, at best, and probably more trouble than it’s worth.

  1. You can use XojoScript perhaps there you can create a class (in code) but still you can wire it up one way and change the xojoscript class anytime (even runtime) by swapping out the xojoscript (or create new instance of your subclassed xojoscript.
    You can even change the context (a special class that giving XojoScript it’s functionality you’ve created).
    It could be a solution to your problem, but it coud as well be not the best solution.

  2. Or maybe you could create a base class in your project and then subclass it, then swap use the Sublass (different type) based on your current project. We use such all the time:

  • Setup some constants boolean or string based compare them at compile time:

    #If UseMySpecialFeature Then
    App.MyFeatues = New MyProFeatures() // Allow pro functionality
    App.MyFeatures = New MyFreeFeatures() // Only allow simple functionality

This will swap code base on UseMySpecialFeature at compile time.
This way you can change the UseMySpecialFeature boolean to True via build script or manually in the ide.

These are just broad ideas for you to examin your best solution.

Flagging with constants, that’s quite clever. I threw the towel and used subclasses that trigger the wiring/hookup on the super.constructor. Since the messaging works with any class and class shared methods I only implemented that one class.

I did learn a couple of things!

NOTE: All observations made on a brand new empty project in 2021 release 2.1. Sample project available.

Introspection.getType() only supports actual object instances. With Xojo.Introspection.GetType() we were able to pass auto while in Introspection.getType() you can not pass a variant.

GetTypeInfo() allows to pass a class.

NOTE: GetTypeInfo() still returns a Xojo.Introspaction.classInfo (debugger & introspection) which is private and part of the deprecated Xojo.Introspaction. The Xojo.Introspaction.classInfo is a subclass of Xojo.Introspection.TypeInfo and thus can be casted to Introspection.TypeInfo.

If GetTypeInfo() allowed to pass a class name in a string (including namespace when required) we could do some nifty dynamic behaviors in Xojo.

In <>, Christian Schmitz suggested a GetTypeInfoWithClassname().

In <> a case was made for it, yet denied because classes may not be included by the compiler.

Im quite certain that at runtime the compiler knows what classes are included/available. A GetTypeInfoWithClassname() method only needs to return NILL if a class doesn’t exist or was unable to resolve the namespace provided.

I created a new feature request: <>