銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

2020年を振り返る

年末にかけて有給を取っていたこともあり、なんとなくプログラミングから離れていたのですが、振り返りは大事ということで振り返っておきたいと思います。

New Relic でのお仕事

昨年4月に転職したので2年目に入ります。徐々に日本法人のお客様も増え、社員も増えるし仕事も増えるという流れが強まる1年でした。実は昨年から今年の最初にかけてはお客様訪問する機会も多くあり、今までとは違った角度で見る機会になりました。また、コロナ流行以降は、本社からの通達でグローバルのすべての拠点が原則封鎖され全員在宅勤務に移行しました。もともと前職から在宅勤務でやっており、特にストレスなく、というより通勤がない分かなり効率的に仕事ができていたので、在宅勤務自体はスムーズに進められました。

仕事としては相変わらずNew Relicのサポートする技術すべてのテクニカルサポートおよび技術発信を行っているので、新しもの好きな私としてはかなり楽しみながらやっています。とはいえ、常に人は足りていない状態なので、もし興味のある方がいればぜひ声をかけてください。

New Relic技術発信については公式ブログに書いているので、個人ブログではあまり書かなくなってしまいました。

田中 孝佳, Author at New Relic公式ブログ

Microsoft MVPをAzureとDevelopment Technologiesで再受賞

毎年再受賞できるかなあと思いつつ発表の日(米国時間7/1)を迎えるのですが、今年はAzureとDevelopment Technologiesの2つのカテゴリで受賞することができました。ただ、やはりこの状況下では活動内容も大きく変わり、オフラインでの勉強会開催がほぼなくなりました。おそらく最後の登壇が1月のIgnite The Tour Osakaだったと思います。それ以降は主にC# Tokyoのオンラインイベントの開催、登壇になりました。

AzureとQ#をほとんどやっていないなあと(仕事や趣味で手は動かしているけど発表できるネタにまでなっていない)思うので、これは来年なにかやりたいなと思っています。

資格

Ignite the Tourの参加でMicrosoft認定資格試験が1回無料で受けられるというのもあって、もう1回分払って「Azure Solutions Architect Expert」を取得しました。ただ、Microsoft的にはAZ-900を取得してほしいらしく、これの取得後もしきりにAZ-900の受験をすすめるDMが届きます。Expertとはいったい...

Microsoftの資格だとExpert以上のものはないし、AWSは会社に詳しい人がわんさかいるのと、そういえばOpenShiftの内部のkubernetesしかちゃんと勉強してないな、ということでCKAとCKAD取得が2021年の目標です。

training.linuxfoundation.org

training.linuxfoundation.org

英語

仕事がら英語は読み書きメインで使うのですが、いままで機械翻訳は「誤りがあるかどうか調べるコストが高くて非効率だ」と思い使わなかったのですが、DeepLの精度の高さに感激したのと処理する量が莫大になってきたので、DeepL Proを契約して使い始めました。

www.deepl.com

これでだいぶ楽にはなったのですが、今度は自分自身の英語力の低下を感じるようになってきたので最近時間をとって勉強するようになりました。

発音はELSAというアプリでやっています。

elsaspeak.com

単語は 英英英単語という、英語で英単語の説明(つまり英英辞典)がしてあるのに加えて日本語訳があるという本で覚えています。

(MP3音声無料DLつき)英語を英語で理解する 英英英単語 上級編

(MP3音声無料DLつき)英語を英語で理解する 英英英単語 上級編

  • 発売日: 2019/02/02
  • メディア: 単行本(ソフトカバー)

文法とリスニングは鬼100則というシリーズが気に入ったので読み進めています。

英文法の鬼100則

英文法の鬼100則

音声DL付き 英語リスニングの鬼100則 (アスカカルチャー)

音声DL付き 英語リスニングの鬼100則 (アスカカルチャー)

  • 作者:米山 明日香
  • 発売日: 2020/07/20
  • メディア: 単行本(ソフトカバー)

学習ではないですが、英語関連ではGrammalyにも課金しています。

app.grammarly.com

その他

在宅でも同じように仕事ができる自分以上に影響を受けてるのが小学生の子供で、休校期間中は勉強するコンテンツ、家の中でも楽しめるコンテンツ(工作が好きなのでペーパークラフトなど)を探したり、よく近くの公園に運動しに行ったりしていました。 学校が再開しても、林間学校的なものは中止になりましたし、運動会も参観できない形になりました。まだしばらくは状況は変わりそうにないので、できる範囲でいろんな体験ができるように考えています。そういう意味で時間に融通の利かせやすい今の仕事はわりと助かっています。

.NET 5 関連の新機能をまとめてみた

11月の.NET Confでリリースが予定されているされた .NET 5 関連の新機能をできるだけまとめてみました。ASP.NET CoreとEF Coreは除いています。

リリースにあわせていくつか更新しています。

そしてそんな .NET 5に興味のある方はぜひこちらのイベントにご参加ください。

csharp-tokyo.connpass.com

.NET 5 のダウンロード

dotnet.microsoft.com

hub.docker.com

.NET 5 のリリースモデル、ロードマップなど

  • リリースは、メジャー、マイナー、サービス更新の3種類から構成されます。
  • .NET 5が「Current」リリースで、1年後にリリース予定の.NET 6が「LTS」となる予定。その後、1年ごとに「Current」「LTS」を交互にリリース予定。
  • Currentは次のメジャーもしくはマイナーリリースがでて3か月、LTSのサポートは3年もしくは次のLTSが出てから1年の長いほう(つまり、最低3年間はサポート)。
  • サポートはマイクロソフトが提供するサポートおよびコミュニティによるサポートが提供されます。Red Hatなどが提供するもの(RHEL向け.NETなど)は別途サポートが提供される場合があります。
  • .NET Framework は4.8が最後のメジャーリリース。ただし、Windowsから削除する予定はなく、サポートとサービス提供は継続予定。

.NET 5のアップデート

  • C# 9とF# 5へアップデート
    • コンパイル時にコード生成を可能にするC# Source Generatorの導入
  • Target Framework (TFM)はクロスプラットフォームなものとOS固有のものを表すものの大きく2種類へ
  • .NETがAPIとして提供しているのに特定のOS(特にWindows)のみで動作するAPI(例えばRegistry.CurrentUser)に対して、使用を検出するアナライザーとコードフィクサーを提供する
  • さまざまなパフォーマンス改善
  • ARM64対応
  • 配布オプションの追加
    • ClickOnceでのクライアントアプリの展開
    • 単一の実行ファイルへの対応
    • コンテナイメージサイズの縮小とcgroup v2への対応
    • Server Coreイメージの追加
  • JsonSerializer の改善 JsonSerializer improvements in .NET 5 · Issue #41313 · dotnet/runtime · GitHub
  • null許容参照型のアノテーション導入の官僚 Annotate remainder of .NET Core assemblies for nullable reference types · Issue #2339 · dotnet/runtime · GitHub
  • .NET5の一部としてWinRT APIをサポート
  • ネイティブコード運用の改善
  • IEEE 754のbinary16 に対応する数値型としてHalf typeの導入
  • self-contained(自己完結型)アプリケーションの配布サイズを小さくするための アプリケーショントリミングの導入
  • アプリケーションコードの潜在的なバグを見つける分析機能を.NET SDKにデフォルトで導入
  • オブザーバビリティ(OpenTelemetry)やマイクロサービス(Tye)対応への取り組みを進める

破壊的変更については以下のドキュメントでまとめられています。

docs.microsoft.com

参考資料

devblogs.microsoft.com

devblogs.microsoft.com

devblogs.microsoft.com

devblogs.microsoft.com

devblogs.microsoft.com

devblogs.microsoft.com

devblogs.microsoft.com

devblogs.microsoft.com

devblogs.microsoft.com

devblogs.microsoft.com

blogs.windows.com

devblogs.microsoft.com

devblogs.microsoft.com

devblogs.microsoft.com

devblogs.microsoft.com

System.Text.JsonやJson.NET で一部だけキーが可変なJSONを処理する

とあるREST APIのエンドポイントが /values/xxx みたいなエンドポイントに対して次のような形式のJSONを返します(実際にはこの3倍くらい属性があり、listの中の配列も多数あります)。XXXで指定した名前の値のリストを取得するというイメージで、この名前のパターンは無数にあります。

{
  "Value": {
    "Key1": "value1",
    "Data": [
      {
        "Timestamp": "2020-10-29T13:02:00.000Z",
        "XXX": 123.45
      },
      {
        "Timestamp": "2020-10-29T13:03:00.000Z",
        "XXX": 456.78
      }
    ]
  }
}

つまり、XXXの部分が可変であるため、単純にC#のクラスにマッピングさせることができないのです。かといって、属性1つのためにJSON全体の構造をdynamicなりJsonDocument(JObject)として扱うのもつらいものがあります。 そこで使える機能が、クラスのメンバーに存在しないJSONのキーをC#側でDictionary型のオブジェクトとして保持することができます。この機能は、System.Text.JsonでもJson.NetでもJsonExtensionDataという同じ名前の属性で使えるのですが、名前空間と指定できる対象が異なります。

Json.NET では名前空間がNewtonsoft.Jsonであり、プロパティもしくはフィールドに指定できます。

www.newtonsoft.com

つぎのようなクラスを用意しておくと、JSONからC#に変換するときはTimestamp以外のJSONのキーとその値は_additionalDataに格納され、C#からJSONに変換するときはこの辞書のキーと値がJSONのキーと値として追加sれます。

public class Data
{
    public DateTime Timestamp{ get; set; }

    [JsonExtensionData]
    private Dictionary<string, JToken> _additionalData;
}

System.Text.Jsonでは名前空間がSystem.Text.Json.Serializationであり、プロパティにしか指定できません。

docs.microsoft.com

public class Data
{
    public DateTime Timestamp{ get; set; }

    [JsonExtensionData]
    public IDictionary<string, object> AdditionalData;
}

このクラスに最初の例のJSONを変換すると、DictionaryにはキーがXXXで値が数値のエントリーが一つ入った状態になります。さて、まずはこれで目的を達したのですが、便利さのためにこのXXXというキーの名前とその数値をKeyNameValueというプロパティに格納することを考えましょう。 Json.NETではドキュメントに書いてある通り、OnDeserialized属性を使って、C#からJSONへの変換が完了したときに実行できるコードをそのクラスの中に定義することができます。

public class Data
{
    public DateTime Timestamp{ get; set; }

    public string KeyName { get; set; }
    public double Value { get; set; }
    
    [JsonExtensionData]
    private Dictionary<string, JToken> _additionalData;

    [OnDeserialized]
    private void OnDeserialized(StreamingContext context)
    {
        var first = segment.ExtensionData.FirstOrDefault();
        if (first.Key != null)
        {
            KeyName = first.Key;
            Value = (double)first.Value;
        }
    }

    public DirectoryAccount()
    {
        _additionalData = new Dictionary<string, JToken>();
    }
}

これに対し、System.Text.Jsonではこのドキュメントにあるとおり、カスタムコンバーターを作成することで対応できます。

docs.microsoft.com

今回のケースだとこのようになるでしょう。

public class GetMetricSegmentCallbacksConverter : JsonConverter<GetMetricSegment>
{
    public override GetMetricSegment Read(
        ref Utf8JsonReader reader,
        Type type,
        JsonSerializerOptions options)
    {
        GetMetricSegment result = JsonSerializer.Deserialize<GetMetricSegment>(ref reader);
            
        var first = result.ExtensionData.FirstOrDefault();
        if (first.Key != null)
        {
            result.Key = first.Key;
            result.Value = (double)first.Value;
        }

        return result;
    }

    public override void Write(
        Utf8JsonWriter writer,
        GetMetricSegment result, JsonSerializerOptions options)
    {
        result.ExtensionData = new Dictionary<string, object>{{result.Key, result.Value}};
        JsonSerializer.Serialize(writer, result);
    }
}

いずれのケースも2つ以上オーバーフローしたキーが格納されているケースなどには対応できないので、適宜APIの仕様に合わせて対応しましょう。