Jump to content
Robert Gilland

Create Class at run time with an AncestorClass and a ClassName

Recommended Posts

I am trying to create a function that creates a class at runtime lie this:

 

function CreateDescentantClass( pcAncestorClass : TClass; const psDescendentClassName : String ): Class;

begin

  Result := psDescendentClassName of  pcAncestorClass;

end;

 

Is this possible? I am using Delphi Alexandria

Share this post


Link to post

Not directly possible. If you explain why you think need that, and given an example of usage (the call!), maybe we can give a better answer...

Share this post


Link to post
2 hours ago, Robert Gilland said:

I am trying to create a function that creates a class at runtime lie this:

 

function CreateDescentantClass( pcAncestorClass : TClass; const psDescendentClassName : String 😞 Class;

begin

  Result := psDescendentClassName of  pcAncestorClass;

end;

 

Is this possible? I am using Delphi Alexandria

Basically you have to enumerate all classes defined in the application and check their classname and ancestry to find one that matches the criteria you pass to the function. So it is misnamed: it does not creaste a class, it searches for one and returns it. The enumeration can be done using the advanced run-time type information support provided by the System.Rtti unit. You start with a variable of type TRttiContext, which has a GetTypes method to enumerate all types that have advanced RTTI info available. You check with the individual types IsInstance property whether it describes a class type, use the AsInstance property to obtain a TRttiInstanceType and use its methods and properties to examine the class to see whether it matches your criteria.

 

There are two drawbacks to be aware of: RTTI generation can be disabled for individual units or even the whole application through compiler switches ($RTTI), so may not be available for 3rd-party classes you use, and RTTI can be used to examine the compiled executable and thus be considered a security risk.

 

If you need this funktionality only for a limited set of classes it may be better to just create your own class registry and register all relevant classes in it in the initialization sections of the relevant units.

Share this post


Link to post

Okay, the requirement is to build a Delphi form descendant from a pre-existing form class adding to it a set of component definitions sent to the Delphi Application in a stream.

The Delphi Application has no prior knowledge on what these components are and where they will be placed.

It does however receive a form name and form version for these components.

The process is already running and working.

But speed is a critical factor and there is a need to increase performance.

As a result of this, my idea is to build a new form class, then store it locally in a component resource file.

Using WriteComponentResFile and ReadComponentResFile functions.

Only when the version of the set of component definitions change then to recreate this resource.

 

 

Share this post


Link to post

Find out where the performance is being lost. Dynamically creating a form instance and it's content like that should be quick. I could see it being slow if it was incrementally built in a way that causes endless events for things like resizing, drawing, layout and themes or something else causing cascading methods/events/etc that could be cleaned up. 

Share this post


Link to post

A TForm is a class. It has some methods to stream in a definition of components that get instantiated on it. That's how the IDE works.

 

Alternatively you can do the exact same thing in code. 

 

The .frm files are simply declarative descriptions of all of the objects, their relationships, and their property values saved from a previous session.

 

If what you've got there isn't running at a comparable speed to what Delphi's IDE is able to do, then I'd guess there's a bottleneck with your code, because there's just not that much going on.

 

Read up on Dependency Injection, which is pretty much what's involved here. And look at Spring4D (or whatever it's called). 

 

I suspect that everything you need is already there. You just need to figure out how to best leverage it.

Share this post


Link to post
12 hours ago, Robert Gilland said:

The process is already running and working.

But speed is a critical factor and there is a need to increase performance. 

Profiling that code is necessary to figure out which component is taking the time, as Brian Evans said above.

 

I use one component which takes 23 ms to execute the create. That is a long time considering there are 5 instances on the form.

 

My fix was to delay creation of the 4 instances not visible.

Share this post


Link to post
9 hours ago, David Schwartz said:

Read up on Dependency Injection, which is pretty much what's involved here. And look at Spring4D (or whatever it's called). 

How should that help ?

Share this post


Link to post
On 4/27/2023 at 3:23 PM, David Schwartz said:

Read up on Dependency Injection, which is pretty much what's involved here. And look at Spring4D (or whatever it's called)

I have downloaded Spring4D. I have looked for something to give me some idea about what it is. 

I cannot understand the purpose of Spring4d is, and I am not sure how it could help me, as I don't know what it is or what it does.

Share this post


Link to post
On 4/27/2023 at 11:19 PM, Robert Gilland said:

I have downloaded Spring4D. I have looked for something to give me some idea about what it is. 

I cannot understand the purpose of Spring4d is, and I am not sure how it could help me, as I don't know what it is or what it does.

 

I believe that Spring4D includes support for DI in it, but that's just based on lots of comments I've seen on this board. That said, in my experience, looking through a code library isn't a very good way to learn new subject matter. 

 

There are several books on Dependency Injection, including one that applies directly to Dephi.

 

https://amzn.to/3LOO6Y9

 

One book that I particularly like is from Mark Seeman, "Dependency Injection in .NET". I have the first edition. The code examples aren't very useful for Dephi, but the principles apply. I think the newer one has more code examples, so it might not be any more useful. However, the code examples wouldn't be hard to translate to Delphi in most cases if you wanted to. I was looking more for understanding the topic, not code examples.

 

https://amzn.to/44c1lJg

 

  • Like 1

Share this post


Link to post
On 4/27/2023 at 8:05 AM, Fr0sT.Brutal said:

How should that help ?

 

On 4/26/2023 at 1:00 AM, Robert Gilland said:

I am trying to create a function that creates a class at runtime

 

He seems to be talking about a Factory pattern. In my mind, that's what DI is involved with: creating instances of things at runtime that may vary in different ways.

 

Edited by David Schwartz

Share this post


Link to post

so you are trying to cache the incoming stream to gain performance

why don't you just feed the form from a local reader instead of downloading it when the version matches?

using the same method

 

I don't think any other solution would pay off in the long run

Share this post


Link to post

@Robert Gilland

 

when you register  a new class, you needs UNregister it when it's not more needs it.

to knows all types registered on system (your app), you can use RTTI query. see this sample

https://docwiki.embarcadero.com/CodeExamples/Sydney/en/Getting_RTTI_for_Rooted_Types_(Delphi)

 

the register is done in "INITIALIZATION" section, and unregister is done in "FINALIZATION" section from unit where this class is defined, normally.

Edited by programmerdelphi2k

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×