2017/1/6にPrecompiled Functionsがサポートされました!! この対応により、C# Scripting (.csx) に比べてかなりAzure Functionsが書きやすくなります。早速Precompiledの利用とこれまでの.csxとの違いを見てみましょう。
Jeremy Hutchinson (@hutchcodes) 2017年1月5日
https://buchizo.wordpress.com/2017/01/06/azure-functions-%E3%81%AE%E3%83%97%E3%83%AA%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88/
- Precompiled Function の概要
- Precompiled Functions を作成してみる
- Precompiled Functions をデプロイする
- Precompiled Functions の課題
- まとめ
Precompiled Function の概要
「ビルド済みのdll」と「dllを使うことを明示したfunction.json」を設置することで、function.jsonで発生していたコンパイルがスキップされ指定したメソッドをエントリポイントとして関数が実行されます。
2017/1/13現在、.NET Framework v4.6 (Full Desktop) がdllの対象となります。このバージョンはAzure App Serviceの制限となるので、将来の.NET Framework対応はそれ待ちです。

なお、.NET Core対応はされていません。すでにIssueに上がっていますが、Microsoft.Azure .WebJobsをはじめとするライブラリやAPIの解決が待たれる状態です。これができると、AWS Lambdaとのマルチクラウドにおけるコード運用も可能になるので、かなりいいのですが..。
実際、最新の1.1.2を試してみても、ね?

さて、改めてPrecompiled Functionsを使う理由ってなんでしょうか? 個人的には、.csxで解消できなかったIDE支援の下でのC#の記述、dllコンパイルによる挙動のわかりやすさ、ローカル環境での動作検証の容易さがその使う理由です。
Pros
ザクッとあげます。要は普通にC# がVisual StudioなどのIDE支援で書けるのって嬉しいですね、デプロイ不要でローカルデバッグできるのいいですね。ということです。
| メリット一覧 | 内容 |
|---|---|
| IDE のフル支援が受けられる | Visual Studio や VS Code をはじめとする任意のIDEでいつも通りC#を書けます。.csx では、インテリセンスをはじめとしたIDE支援が制限された中で書くことが強いられていたため、普通にかけるのは嬉しいものです。 |
| ローカル動作の確認 | dllにコンパイル済みなので、些細なミスによるコンパイル失敗を避けられます。些細なのですが、;忘れだったり結構IDEに頼っていることを自覚させられる生活から解放されます。*1 |
| 一定の動作保証 | ローカルで動作確認した上でCI/CDするため、おおよそ意図通り動くことが期待できます。*2 |
Cons
Web UIでの編集ができない。の一言です。AWS LambdaにおけるJavaやC# (.NET Core) と同じです。
実際、Precompiled FunctionsはWeb UI上でみてもコードは表示されず文字化け状態で表示されます。*3

Precompiled Functions を作成してみる
ミニマムコードサンプルはWikiにあります。
https://github.com/Azure/azure-webjobs-sdk-script/wiki/Precompiled-functions
今回は、ミニマムコードにないLoggerを含めてやってみましょう。コードはいつも通り、GitHubに挙げておきました。PrecompileFunctions.slnにソースをいれてあります。
コード全体像は次の通りです。
https://gist.github.com/guitarrapc/1530d1066f0dd57db338669a15bf5792
このプロジェクトをビルドすればルート直下にPreCompileEnvironmentVariablesフォルダを作成して、ビルド済みdll、function.jsonが一緒に配置されます。ちなみに、nugetパッケージを一切追加しない状態だと次のようなエラーが出ます。そこで、必要なパッケージを追加して解決しています。

テストすると、上手く動きましたね?

エントリポイントのメソッドを含めるクラスの注意
dllを配置した場合のエントリポイントは、function.jsonに記述した次の2文で指定します。
"scriptFile": "PreCompileEnvironmentVariables.dll", "entryPoint": "PreCompileEnvironmentVariables.MyFunction.Run",
| キー | 設定する内容 |
|---|---|
| scriptFile | コンパイルしたエントリポイントとなるdll を指定します。 |
| entryPoint | NameSpace.Class.Methodの形式でエントリポイントを指定します。 |
例では、MyFunctionクラスのMyFunctionメソッドをエントリポイントに指定しています。このMyFunctionメソッドを含むMyFunctionクラスには、MyFunctionメソッド以外を含めるとエントリポイントを見つけられないようです。つまり、インスタンスフィールドなどは書かず、MyFunctionメソッドだけ書いてください。
帝国兵 (@superriver) January 10, 2017
ロガーについて
ロガーを利用するにはMicrosoft.Azure.WebJobs nugetパッケージの追加をしましょう。ミニマムコードのRunメソッドシグネチャにMicrosoft.Azure.WebJobsがありませんが、実は渡ってきています。このnugetパッケージがあれば、.csx同様にTraceWriterを実装せずともロガーとして利用できます。
これにより、エントリポイントのメソッドシグネチャはpublic static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)のように書けます。これでこれまで通り、public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)とするだけでロギングできて便利!
HttpRequestMessageの拡張メソッドについて
.csxと同じようにHttpRequestMessageの拡張メソッドを利用するため、HttpRequestMessage nugetパッケージの追加をしましょう。これにより、HttpRequestMessageなどが利用可能になります。

Precompiled Functions をデプロイする
いよいよPrecompiled Functionsをデプロイしましょう。GitHubによるCDでやってみます。
従来のdeployment.cmdにmsbuildのセクションを追加しました。diffはこの通りです。
https://gist.github.com/guitarrapc/e29e7c90b306aa2d66ca3815b0b16731
上手くデプロイされるとFunctionsがビルド後に展開され、Web UIからも見えるはずです。



ただし、w3wp.exeによるdllロック問題があるので、2度目以降のデプロイ時にはKuduコンソールでw3wp.exeをkill、Web UIでのRestartをしてあげてください。
帝国兵 (@superriver) January 10, 2017
この問題はすでに報告済みなので、解決を待ちましょう。*4
https://github.com/Azure/azure-webjobs-sdk-script/issues/1105
Precompiled Functions の課題
いくつか使いにくいポイントが残っています。
ビルド
今回、.slnの配置、ビルド生成物の配置をいじっていますが、CI -> CDの連携に工夫がいるのはちょっとまだ使いにくいです。もう少しいい感じでデプロイできるといいのですが。
DLLロック
現状では、Web AppsのAPI経由、Kudu API経由などでw3wpやサイトのリスタートが必要です。結構ヤなポイントなので、これは解消しないと使いにくいです。 コンテナベースになれば手っ取り早いですが、Azure Functionsのコンテナ化はまだ先の話でしょう。
.NET Core 対応
いずれするでしょう。待ちです。
まとめ
かなりいい感じで利用できます。dllの文字化けが表示されるのは愛嬌ということで。
が、dllロックは結構厄介なので、これが解消するのを待って本番に入れたいところです。AWS Lambdaが主軸なのですが、サブとしてAzure Functionsは優秀なので、.NET Core対応も待ち望ましいですね。