tech.guitarrapc.cóm

Technical updates

Azure Functions で C# の拡張メソッドを定義、利用してみた

最近 Azure Functions の記事しか書いてませんが、それぐらいの価値があるサービスなので AWS Lambda 以外にも把握、活用しておくといいともいます。

これまで、C# Script (.csx) をAzure Functions で利用してきました。利用、CI、外部ライブラリ(NuGet) の利用ときましたが最後に重要な確認があります、拡張メソッドです。

tech.guitarrapc.com

tech.guitarrapc.com

tech.guitarrapc.com

C# で拡張メソッドがどう使えるかは触り心地にとって非常に重要です。そこで今回は 拡張メソッドの定義、利用について見てみましょう。

目次

拡張メソッドの利用

拡張メソッドについては、MSDN や C# の鉄板サイトを見ればいいでしょう。拡張メソッドを自前で定義できないことには、やはり結構厳しいものです。

ufcpp.net

拡張メソッドの定義方法は、次の通りと紹介されています。

「静的クラス」中に、 第一引数に this キーワードを修飾子として付けた static メソッドを書きます。

つまり以下のようなものです。

static class EnumerableExtensions
{
    public static string ToJoinedString<T>(this IEnumerable<T> source, string separator = "")
    {
        return string.Join(separator, source);
    }
}

今回はこの拡張メソッドを Azure Functionsで定義利用します。

Azure Functions 上で拡張メソッドの定義

さて、単純に上記のコードを Azure Functions にそのまま持って行ってみます。すると以下のエラーでコンパイルに失敗します。

error CS1109: Extension methods must be defined in a top level static class; EnumerableExtensions is a nested class

これは、Azure Functions をぱっと見れば分かる通り、表示されていませんがクラスが外側にあるためとわかります。

#r "Newtonsoft.Json"

using System;
using System.Net;
using System.Threading.Tasks;
using Newtonsoft.Json;

public static async Task<object> Run(HttpRequestMessage req, TraceWriter log)
{
    log.Verbose($"Webhook was triggered!");

    string jsonContent = await req.Content.ReadAsStringAsync();
    dynamic data = JsonConvert.DeserializeObject(jsonContent);

    if (data.first == null || data.last == null) {
        return req.CreateResponse(HttpStatusCode.BadRequest, new {
            error = "Please pass first/last properties in the input object"
        });
    }

    return req.CreateResponse(HttpStatusCode.OK, new {
        greeting = $"Hello {data.first} {data.last}!"
    });
}

そして、Azure Functions はインスタンス化する必要がないので、おそらく静的クラスでしょう。つまり以下のように直接拡張メソッドを定義可能です。

無事に コンパイルされました。

利用もいつもどおりです。

gist.github.com

まとめ

今回のサンプルも載せておきました。

github.com

グラニでは、すでに開発の通知周りの多くを Azure Functions に移行完了しており、すでに本番稼働しています。もちろん複数の手段を保ちつつですが、GitHub Webhook の Chatwork 通知など多くの処理が Azure Functions で動いています。通知のほんの少しでも画面に収まらないんですね...。

ちなみにグラニでは、master ブランチへの push/merge を起点に Github CI されるように組んであります。このため、開発者はAzure Portal に入ることなく Visuals Studio や VS Code で書いて、push、自動的にデプロイと完結します。

AWS Lambda が出る前のプレビューから言い続けていた C# サポートが先に Azure に出ました。とは言え、AWS Lambda は AWSリソース操作など多くの点で活用していますしそれは変わりません。しかし、C# で何ら変わらず制約もなく普通に書ける良さ、CI が容易であることはとってもいいです。APIGateway + AWS Lambda の Failover 先としての Azure Functions という使い方もしています。

CI なども含めた総合的な活用しやすさでいうと、AWS Lambda を上回っています。ただ、API Gateway + AWS Lambda は別の更なる価値もあったりするので、優劣というより使い方次第だと思います。

現時点では、モニタリングがないため「実行が後から追えない」ものの、現時点では抜けもなく通知されています。

是非皆さんも楽しんでください。