Ability to use third party libraries?

Sorry if I missed this in the docs, but am I able to use #Script to build (essentially) full blown apps in which I can import third party libraries? Or is it only “locked down” to libraries that have been built into #Script?

For example, we’d like to build an email service using AWS SES and it’s relative library. Can I build something like this in #Script as if it was built in C# and compiled? This is just one example. Another example might be some other third party library we want to import and write complex code against, but have this in #Script instead so we can execute at runtime without having to compile it beforehand into a DLL.

There’s no facility specific to #Script itself to import external .NET libraries/packages, you could do something like use its Scripting .NET functionality to load an Assembly’s .dll bytes from an external URL loaded from urlContents, but it’s typically for use as a “glue” scripting language to script existing .NET functionality, the primary supported mechanism of which is to drop .NET .dll's in your App’s /plugins folder where any Script Methods, Blocks, Sharp Code Pages, etc will be automatically available to your scripts.

You can define reusable functions in #Script code function or lisp defn script blocks, but you’re still only creating reusable scripts, not importing external .dll’s or packages.

Because of Lisp’s dynamism’s and unique characteristics, #Script Lisp does have better support for importing and loading external code, from both local .l source files or from remote URLs.

Your AWS SES example use-case happens to be very similar to the TCP Lisp REPL Demo where it establishes a remote Lisp TCP REPL connection with the live techstacks.io Server, loads a remote parse-rss lisp function which is used to parse Hacker News RSS Feed into a .NET Collection and used to construct an email body with HN’s current Top 5 links that it sends to all admin users by using DB Scripts to get the emails of all admin users and sends them emails by publishing 5x SendEmail Request DTOs using the publishMessage ServiceStack Script where they’re processed in the background by its configured MQ Server that uses it to execute the SendEmail ServiceStack Service where it uses its configured AWS SES SMTP Server to finally send out the Emails.

This is typical to how you would use #Script, i.e. you would use it to call existing IOC dependencies and Services, you wouldn’t use it for example to create the SMTP Client or Background MQ Server from scratch.

I see. So essentially, I write a custom Library (which itself can reference other libraries as usual) and then add this as a #Script Plugin. Then, I can write scripts that can call this library, and passing in appropriate parameters, etc which itself can be dynamic and pull values from say AutoQuery, Ormlite, etc?

Right, plugins are the way to enable external .dll's in Sharp Apps (i.e. Apps written entirely in #Script).

If you wanted to extend an existing .NET Core App enhanced with #Script you would just be registering your Script plugins directly with SharpPagesFeature Plugin:

Plugins.Add(new SharpPagesFeature {
    Args = { ... },              // Global Arguments available to all Scripts, Pages, Partials, etc
    ScriptMethods = { ... },     // Additional Methods
    ScriptBlocks = { ... },      // Additional Script Blocks 
    FilterTransformers = { .. }, // Additional Stream Transformers
    PageFormats = { ... },       // Additional Text Document Formats
    Plugins = { ... },           // Encapsulated Features e.g. Markdown, Protected or ServiceStack Features

    ScanTypes = { ... },         // Auto register Methods, Blocks and Code Page Types
    ScanAssemblies = { ... },    // Auto register all Methods, Blocks and Code Page Types in Assembly
});

The most flexible way to register a suite of functionality with a ScriptContext is to implement IScriptPlugin which will let you register all the above functionality encapsulated in a single class, e.g. here is how MarkdownScriptPlugin.cs is configured:

public class MarkdownScriptPlugin : IScriptPlugin
{
    public bool RegisterPageFormat { get; set; } = true;

    public void Register(ScriptContext context)
    {
        if (RegisterPageFormat)
            context.PageFormats.Add(new MarkdownPageFormat());
        
        context.FilterTransformers["markdown"]=MarkdownPageFormat.TransformToHtml;
        
        context.ScriptMethods.Add(new MarkdownScriptMethods());
        
        context.ScriptBlocks.Add(new MarkdownScriptBlock());
    }
}

Which if it weren’t already pre-registered by default, could be easily registered with:

Plugins.Add(new SharpPagesFeature {
     Plugins = { new MarkdownScriptPlugin() }
})