Gradle 7.1 and project.getConvention() deprecation

Say, I am writing a plugin and have a function I’d like to expose in my gradle scripts and with the deprecation of project.getConvention(), and future removal of this API in 8.0. Could someone please help me understand how I can use the extension API to achieve the same thing?

For example,

I’d like to expand foo() as a dynamic function in my gradle file, e.g. similar to this:

plugins { 
     id "cpp-application"
     id "my-plugin-here"
 }

application {

    dependencies {
         implementation foo(...) 
    } 
} 

The intention of foo is that it’s a global function that would return e.g. a String representing “com.company.package:package:1.0” or a project if found locally in my build.

To achieve this, I’ve used the project.getConvention().getPlugins().put(“whatever”, new foo())

And I create a class foo that does something similar to

class foo {
    ...
    Object foo(String value) {
        Project p = project.findProject(value);
            if (p != null) {
                return p;
            } 
            return "com.company.package:package:1.0";
       }
}

There are other cases where this notation is very useful and doesn’t require much code to set that up. The one point here is that it exposes foo() and it can be used wherever in the build.gradle script.

Furthermore, say I have a function bar that takes a closure. I want to execute this within the application {} closure. Using the project.getExtensions().add(), or create() will from my understanding create the extension “bar” there, but how can I ensure appropriate execution of e.g. function bar when bar takes a closure?

Essentially, I want to execute this function arbitrarily within the script, e.g. within the application { } closure. And I take it that the extension API sets this up as application {}, then foo {} and foo {} becomes it’s own namespace. The documentation on this is a bit terse and the Internet lack examples of this.