Guida di riferimento per gli sviluppatori di Funzioni di Azure in F#Azure Functions F# Developer Reference

F# per Funzioni di Azure è una soluzione che consente di eseguire facilmente piccole parti di codice, o "funzioni", nel cloud.F# for Azure Functions is a solution for easily running small pieces of code, or "functions," in the cloud. I dati vengono trasmessi alla funzione F# tramite argomenti della funzione.Data flows into your F# function via function arguments. I nomi di argomento sono specificati in function.jsone sono disponibili nomi predefiniti per l'accesso a elementi quali il logger delle funzioni e i token di annullamento.Argument names are specified in function.json, and there are predefined names for accessing things like the function logger and cancellation tokens.

Questo articolo presuppone che l'utente abbia già letto Guida di riferimento per gli sviluppatori di Funzioni di Azure.This article assumes that you've already read the Azure Functions developer reference.

Funzionamento del file con estensione fsxHow .fsx works

Un file .fsx è uno script F#.An .fsx file is an F# script. Può essere considerato un progetto F# contenuto in un singolo file.It can be thought of as an F# project that's contained in a single file. Il file contiene il codice per il programma (in questo caso la funzione di Azure) e direttive per la gestione delle dipendenze.The file contains both the code for your program (in this case, your Azure Function) and directives for managing dependencies.

Quando si usa un file .fsx per una funzione di Azure, gli assembly normalmente necessari sono inclusi automaticamente, consentendo di concentrarsi sulla funzione anziché sul codice "boilerplate".When you use an .fsx for an Azure Function, commonly required assemblies are automatically included for you, allowing you to focus on the function rather than "boilerplate" code.

Associazione agli argomentiBinding to arguments

Ogni associazione supporta set di argomenti, come descritto nei dettagli in Guida di riferimento per gli sviluppatori di trigger e associazioni di Funzioni di Azure.Each binding supports some set of arguments, as detailed in the Azure Functions triggers and bindings developer reference. Ad esempio, una delle associazioni di argomento supportate da un trigger del BLOB è un oggetto POCO, che può essere espresso con un record F#.For example, one of the argument bindings a blob trigger supports is a POCO, which can be expressed using an F# record. Ad esempio:For example:

type Item = { Id: string }

let Run(blob: string, output: byref<Item>) =
    let item = { Id = "Some ID" }
    output <- item

La funzione F# di Azure richiederà uno o più argomenti.Your F# Azure Function will take one or more arguments. Per "argomenti di Funzioni di Azure" si intendono argomenti di input e argomenti di output.When we talk about Azure Functions arguments, we refer to input arguments and output arguments. Un argomento di input rappresenta un input per la funzione F# di Azure.An input argument is exactly what it sounds like: input to your F# Azure Function. Un argomento di output è costituito da dati modificabili oppure è un argomento byref<> usato per passare di nuovo dati in uscita dalla funzione.An output argument is mutable data or a byref<> argument that serves as a way to pass data back out of your function.

Nell'esempio precedente, blob è un argomento di input, mentre output è un argomento di output.In the example above, blob is an input argument, and output is an output argument. Si noti che è stato usato byref<> per output. Non è necessario aggiungere l'annotazione [<Out>].Notice that we used byref<> for output (there's no need to add the [<Out>] annotation). L'uso di un tipo byref<> consente alla funzione di cambiare il record o l'oggetto cui l'argomento fa riferimento.Using a byref<> type allows your function to change which record or object the argument refers to.

Quando un record F# viene usato come tipo di input, la definizione del record deve essere contrassegnata con [<CLIMutable>] per consentire al framework di Funzioni di Azure di impostare i campi in modo appropriato prima di passare il record alla funzione.When an F# record is used as an input type, the record definition must be marked with [<CLIMutable>] in order to allow the Azure Functions framework to set the fields appropriately before passing the record to your function. [<CLIMutable>] genera setter in background per le proprietà del record.Under the hood, [<CLIMutable>] generates setters for the record properties. Ad esempio:For example:

[<CLIMutable>]
type TestObject =
    { SenderName : string
      Greeting : string }

let Run(req: TestObject, log: TraceWriter) =
    { req with Greeting = sprintf "Hello, %s" req.SenderName }

Una classe F# può essere usata negli argomenti di input e di output.An F# class can also be used for both in and out arguments. Per una classe, le proprietà necessitano in genere di getter e setter.For a class, properties will usually need getters and setters. Ad esempio:For example:

type Item() =
    member val Id = "" with get,set
    member val Text = "" with get,set

let Run(input: string, item: byref<Item>) =
    let result = Item(Id = input, Text = "Hello from F#!")
    item <- result

RegistrazioneLogging

Per registrare l'output nei log in streaming in F#, la funzione deve accettare un argomento di tipo TraceWriter.To log output to your streaming logs in F#, your function should take an argument of type TraceWriter. Per coerenza è consigliabile denominare questo argomento log.For consistency, we recommend this argument is named log. Ad esempio:For example:

let Run(blob: string, output: byref<string>, log: TraceWriter) =
    log.Verbose(sprintf "F# Azure Function processed a blob: %s" blob)
    output <- input

AsyncAsync

È possibile usare il flusso di lavoro async, ma il risultato deve restituire un oggetto Task.The async workflow can be used, but the result needs to return a Task. Questa operazione può essere eseguita con Async.StartAsTask, ad esempio:This can be done with Async.StartAsTask, for example:

let Run(req: HttpRequestMessage) =
    async {
        return new HttpResponseMessage(HttpStatusCode.OK)
    } |> Async.StartAsTask

Token di annullamentoCancellation Token

Se la funzione deve gestire l'arresto normale, è possibile assegnarle un argomento CancellationToken .If your function needs to handle shutdown gracefully, you can give it a CancellationToken argument. È possibile combinare questo argomento con async, ad esempio:This can be combined with async, for example:

let Run(req: HttpRequestMessage, token: CancellationToken)
    let f = async {
        do! Async.Sleep(10)
        return new HttpResponseMessage(HttpStatusCode.OK)
    }
    Async.StartAsTask(f, token)

Importazione di spazi dei nomiImporting namespaces

Gli spazi dei nomi possono essere aperti nel modo consueto:Namespaces can be opened in the usual way:

open System.Net
open System.Threading.Tasks

let Run(req: HttpRequestMessage, log: TraceWriter) =
    ...

I seguenti spazi dei nomi vengono aperti automaticamente:The following namespaces are automatically opened:

  • System
  • System.Collections.Generic
  • System.IO
  • System.Linq
  • System.Net.Http
  • System.Threading.Tasks
  • Microsoft.Azure.WebJobs
  • Microsoft.Azure.WebJobs.Host.Microsoft.Azure.WebJobs.Host.

Riferimento ad assembly esterniReferencing External Assemblies

In maniera analoga, i riferimenti per l'assembly del framework possono essere aggiunti con la direttiva #r "AssemblyName" .Similarly, framework assembly references can be added with the #r "AssemblyName" directive.

#r "System.Web.Http"

open System.Net
open System.Net.Http
open System.Threading.Tasks

let Run(req: HttpRequestMessage, log: TraceWriter) =
    ...

Gli assembly seguenti vengono aggiunti automaticamente dall'ambiente di hosting di Funzioni di Azure:The following assemblies are automatically added by the Azure Functions hosting environment:

  • mscorlib,mscorlib,
  • System
  • System.Core
  • System.Xml
  • System.Net.Http
  • Microsoft.Azure.WebJobs
  • Microsoft.Azure.WebJobs.Host
  • Microsoft.Azure.WebJobs.Extensions
  • System.Web.Http
  • System.Net.Http.Formatting.System.Net.Http.Formatting.

Gli assembly seguenti sono anche casi speciali ai quali è possibile fare riferimento tramite simplename, ad esempio #r "AssemblyName":In addition, the following assemblies are special cased and may be referenced by simplename (e.g. #r "AssemblyName"):

  • Newtonsoft.Json
  • Microsoft.WindowsAzure.Storage
  • Microsoft.ServiceBus
  • Microsoft.AspNet.WebHooks.Receivers
  • Microsoft.AspNEt.WebHooks.Common.Microsoft.AspNEt.WebHooks.Common.

Per fare riferimento a un assembly privato è possibile caricare il file dell'assembly in una cartella bin relativa alla funzione e farvi riferimento usando il nome file, ad esempio #r "MyAssembly.dll".If you need to reference a private assembly, you can upload the assembly file into a bin folder relative to your function and reference it by using the file name (e.g. #r "MyAssembly.dll"). Per informazioni su come caricare i file nella cartella della funzione vedere la sezione seguente sulla gestione dei pacchetti.For information on how to upload files to your function folder, see the following section on package management.

Codice introduttivo dell'editorEditor Prelude

Un editor che supporta i servizi di compilazione F# non è in grado di riconoscere gli spazi dei nomi e gli assembly inclusi automaticamente con Funzioni di Azure.An editor that supports F# Compiler Services will not be aware of the namespaces and assemblies that Azure Functions automatically includes. Può quindi essere utile includere un codice introduttivo che consenta all'editor di trovare gli assembly usati e di aprire in modo esplicito gli spazi dei nomi.As such, it can be useful to include a prelude that helps the editor find the assemblies you are using, and to explicitly open namespaces. Ad esempio:For example:

#if !COMPILED
#I "../../bin/Binaries/WebJobs.Script.Host"
#r "Microsoft.Azure.WebJobs.Host.dll"
#endif

open Sytem
open Microsoft.Azure.WebJobs.Host

let Run(blob: string, output: byref<string>, log: TraceWriter) =
    ...

Quando esegue il codice, Funzioni di Azure elabora l'origine con COMPILED definito, quindi il codice introduttivo dell'editor verrà ignorato.When Azure Functions executes your code, it processes the source with COMPILED defined, so the editor prelude will be ignored.

Gestione dei pacchettiPackage management

Per usare i pacchetti NuGet in una funzione F#, aggiungere un file project.json nella cartella della funzione nel file system dell'app per le funzioni.To use NuGet packages in an F# function, add a project.json file to the the function's folder in the function app's file system. Di seguito è riportato un esempio di file project.json che aggiunge un riferimento ai pacchetti NuGet a Microsoft.ProjectOxford.Face versione 1.1.0:Here is an example project.json file that adds a NuGet package reference to Microsoft.ProjectOxford.Face version 1.1.0:

{
  "frameworks": {
    "net46":{
      "dependencies": {
        "Microsoft.ProjectOxford.Face": "1.1.0"
      }
    }
   }
}

È supportato solo .NET Framework 4.6, quindi verificare che nel file project.json sia specificato net46 come qui illustrato.Only the .NET Framework 4.6 is supported, so make sure that your project.json file specifies net46 as shown here.

Quando si carica un file project.json , il runtime ottiene i pacchetti e aggiunge automaticamente riferimenti agli assembly dei pacchetti.When you upload a project.json file, the runtime gets the packages and automatically adds references to the package assemblies. Non è necessario aggiungere direttive #r "AssemblyName" .You don't need to add #r "AssemblyName" directives. È sufficiente aggiungere le istruzioni open necessarie al file .fsx.Just add the required open statements to your .fsx file.

Si consiglia di inserire gli assembly con riferimento automatico nel codice introduttivo dell'editor, per migliorare l'interazione dell'editor con i servizi di compilazione F#.You may wish to put automatically references assemblies in your editor prelude, to improve your editor's interaction with F# Compile Services.

Come aggiungere un file project.json alla funzione di AzureHow to add a project.json file to your Azure Function

  1. Assicurarsi prima di tutto che l'app di funzione sia in esecuzione aprendo la funzione nel portale di Azure.Begin by making sure your function app is running, which you can do by opening your function in the Azure portal. In questo modo è anche possibile accedere ai log in streaming in cui verrà visualizzato l'output di installazione dei pacchetti.This also gives access to the streaming logs where package installation output will be displayed.
  2. Per caricare un file project.json , usare uno dei metodi descritti in Come aggiornare i file delle app per le funzioni.To upload a project.json file, use one of the methods described in how to update function app files. Se si usa la distribuzione continua per Funzioni di Azure, è possibile aggiungere un file project.json al ramo di staging per eseguire qualche esperimento prima di aggiungerlo al ramo di sviluppo.If you are using Continuous Deployment for Azure Functions, you can add a project.json file to your staging branch in order to experiment with it before adding it to your deployment branch.
  3. Dopo l'aggiunta del file project.json , l'output visualizzato nel log in streaming della funzione sarà simile all'esempio seguente:After the project.json file is added, you will see output similar to the following example in your function's streaming log:
2016-04-04T19:02:48.745 Restoring packages.
2016-04-04T19:02:48.745 Starting NuGet restore
2016-04-04T19:02:50.183 MSBuild auto-detection: using msbuild version '14.0' from 'D:\Program Files (x86)\MSBuild\14.0\bin'.
2016-04-04T19:02:50.261 Feeds used:
2016-04-04T19:02:50.261 C:\DWASFiles\Sites\facavalfunctest\LocalAppData\NuGet\Cache
2016-04-04T19:02:50.261 https://api.nuget.org/v3/index.json
2016-04-04T19:02:50.261
2016-04-04T19:02:50.511 Restoring packages for D:\home\site\wwwroot\HttpTriggerCSharp1\Project.json...
2016-04-04T19:02:52.800 Installing Newtonsoft.Json 6.0.8.
2016-04-04T19:02:52.800 Installing Microsoft.ProjectOxford.Face 1.1.0.
2016-04-04T19:02:57.095 All packages are compatible with .NETFramework,Version=v4.6.
2016-04-04T19:02:57.189
2016-04-04T19:02:57.189
2016-04-04T19:02:57.455 Packages restored.

Variabili di ambienteEnvironment variables

Per ottenere una variabile di ambiente o un valore di impostazione dell'app, usare System.Environment.GetEnvironmentVariable, ad esempio:To get an environment variable or an app setting value, use System.Environment.GetEnvironmentVariable, for example:

open System.Environment

let Run(timer: TimerInfo, log: TraceWriter) =
    log.Info("Storage = " + GetEnvironmentVariable("AzureWebJobsStorage"))
    log.Info("Site = " + GetEnvironmentVariable("WEBSITE_SITE_NAME"))

Riutilizzo del codice del file con estensione fsxReusing .fsx code

È possibile usare il codice di altri file .fsx tramite una direttiva #load.You can use code from other .fsx files by using a #load directive. ad esempio:For example:

run.fsx

#load "logger.fsx"

let Run(timer: TimerInfo, log: TraceWriter) =
    mylog log (sprintf "Timer: %s" DateTime.Now.ToString())

logger.fsx

let mylog(log: TraceWriter, text: string) =
    log.Verbose(text);

I percorsi specificati per la direttiva #load sono relativi alla posizione del file .fsx.Paths provides to the #load directive are relative to the location of your .fsx file.

  • #load "logger.fsx" carica un file che si trova nella cartella della funzione.#load "logger.fsx" loads a file located in the function folder.
  • #load "package\logger.fsx" carica un file che si trova nella sottocartella package della cartella della funzione.#load "package\logger.fsx" loads a file located in the package folder in the function folder.
  • #load "..\shared\mylogger.fsx" carica un file che si trova nella cartella shared allo stesso livello della cartella della funzione, ovvero direttamente in wwwroot.#load "..\shared\mylogger.fsx" loads a file located in the shared folder at the same level as the function folder, that is, directly under wwwroot.

La direttiva #load funziona solo con i file .fsx (script F# ), non con i file .fs.The #load directive only works with .fsx (F# script) files, and not with .fs files.

Passaggi successiviNext steps

Per altre informazioni, vedere le seguenti risorse:For more information, see the following resources: