Reuse your C# Script (csx) code in multiple Azure Functions

Azure Functions hit GA (General Availability) recently. A big milestone for the Azure Functions team, and I'm happy to see that it's finally out of Preview.

Lately I've been working a lot with various parts of Azure to find the best fit for various busines cases. Functions has been one of those adventures, doing a lot of R&D around how they can be put to good use. One of the pitfalls I found early on was that I wanted to have multiple functions process different things on the same "task". With that I also had various helper methods I wanted to load in each function, but I didn't want to re-write them in each and every one of them.

With that said, this post is simply about how you can load the same code in multiple functions without having to re-invent yourself. Think of a shared C# script (csx) file as a user control or component you'd inject.

Sharing code between Azure Functions

For the sake of the sample, I've created new functions which are without the read business logic, as that would clutter the samples. As such, the samples here illustrate how you can share code between your Azure Functions only.

Create a folder for your reusable code

There's various ways to go ahead and create this shared folder. If you're developing using the CLI and file system you can do it there, or if you're developing using the browser you can easily do it from Kudu etc.

I'll show you how to creat the shared file using Kudu.

Navigate to your Azure Function app service Kudu Debug Console, which is prefixed with your function name, like this:

https://zimmergrenfunctionsdemo.scm.azurewebsites.net/DebugConsole

Next, navigate to \home\site\wwwroot which should list your functions and the host.json file etc. Click the [+]-sign and create a new folder:

I'm creating a folder called Shared since this is what we see as a practice from the Azure team as well. In there, I'm creating my CustomerHelper.csx file which will contain the reusable code snippets I need.

CustomerHelper.csx content

In the new file, I've added some basic sample code to illustrate the idea.

using System;

public static class CustomerHelper 
{
	public static CustomerInformation GetCustomerData(string customerId)
	{
        // NOTE: For demo purposes only...
        
        // Return a new CustomerInformation object, which is also in this shared file.
        return new CustomerInformation{
            CustomerName = "Sample Customer 1", 
            CustomerId = "customerid-12345", 
            CustomerAddress = "Home Sweet Home", 
            IsRecurringCustomer = true
        };
	}
}

// CustomerInformation object, in the shared file so we can access it from any function.
public class CustomerInformation
{
    public string CustomerName { get;set; }
    public string CustomerId { get; set; }
    public string CustomerAddress { get; set; }
    public bool IsRecurringCustomer {get;set; }
}

Referencing your shared code from your Azure Functions

Great. We have a shared code snippet in our CustomerHelper.csx now, containing a simple method for getting customer details and it returns a strongly typed CustomerInformation object.

This is what one of my Azure Functions look like, simply referencing the code in the shared code file:

#load "../Shared/CustomerHelper.csx"

using System;

public static void Run(string input, TraceWriter log)
{
    log.Info("Getting customer info...");

    var customerInfo = CustomerHelper.GetCustomerData(input);

    log.Info("==== CUSTOMER INFO ====");
    log.Info($"Customer Id: {customerInfo.CustomerId}");
    log.Info($"Customer Name: {customerInfo.CustomerName}");
    log.Info($"Customer Address: {customerInfo.CustomerAddress}");
    log.Info($"Returning Customer?: {customerInfo.IsRecurringCustomer}");
    log.Info("=======================");
}

You use the #load statement to point to your code that you want to import into this file.

Read more on C# Script and the #load statement: https://msdn.microsoft.com/en-us/magazine/mt614271.aspx?f=255&MSPPError=-2147217396

Running this function will show your the information in the log, as per the snippet:

2016-12-01T23:05:50.014 Function started (Id=c8f41956-b2dc-4a8c-833e-1ec341d859eb)
2016-12-01T23:05:50.014 Getting customer info...
2016-12-01T23:05:50.014 ==== CUSTOMER INFO ====
2016-12-01T23:05:50.014 Customer Id: customerid-12345
2016-12-01T23:05:50.014 Customer Name: Sample Customer 1
2016-12-01T23:05:50.014 Customer Address: Home Sweet Home
2016-12-01T23:05:50.014 Returning Customer?: True
2016-12-01T23:05:50.014 =======================
2016-12-01T23:05:50.014 Function completed (Success, Id=c8f41956-b2dc-4a8c-833e-1ec341d859eb)

Done! That's all there's to it. I hope it helps.

Cheers,Tobias.