しばやん雑記

ASP.NET とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure App Service が .NET Framework 4.7.2 に対応

予定では 10 月中旬にデプロイされる予定だった App Service の .NET Framework 4.7.2 対応ですが、今日にようやくデプロイが行われたようです。

手元にある Japan East と Central US の Scale unit で確認していますが、全ての Scale unit にデプロイされたかは公式のアナウンスを待つ必要があります。*1

f:id:shiba-yan:20181108143352p:plain

そろそろ appservice.info も複数リージョンにデプロイして、情報を集約出来るようにしたいです。

Visual Studio 2017 でもちょっと前に Installer から .NET 4.7.2 SDK がインストール出来るようになっているので、これで新しい機能を使う準備が整った形ですね。異常なほど時間かかりましたけど。

.NET Framework 4.7.2 での更新内容は以下のページを参照してください。

What's new in the .NET Framework | Microsoft Docs

大きな機能追加とかはないですが、バグ修正やパフォーマンス改善など細々としたものが多いです。信頼性の向上としては重要です。セキュリティ周りとコレクション、そして ASP.NET を見ておけば良いです。

今回のバージョンは暗号化周りで API が結構追加されています。個人的には Rfc2898DeriveBytes で HMAC-SHA256 が選べるようになったのは良い感あります。対応が遅すぎるという気もしないこともないですが、BCL レベルで入ったのは良いです。

大きく挙動が変わるものは無さそうなので、.NET 4.7.2 に再ターゲットしつつ検証すればよいかと思います。

おまけ : ASP.NET Web Forms の DI 対応

.NET Framework 4.7.2 での割と大きめの機能追加が ASP.NET Web Forms 向けの DI です。

こういうことを書くと今更 Web Forms かとか言われそうですが、Web Forms から ASP.NET Core MVC への移行を考えた場合には、適切に Web Forms のコードビハインドから処理が分離されていることが重要なので、まずは DI を使って処理を別のプロジェクトに分けるのは必要だと思ってます。

特に ASP.NET Core は全てが DI で解決されるので、そのスタイルに持って行った方がスムーズです。

4.7.2 がリリースされた当初はイマイチ情報が少なくて面倒でしたが、最近は Unity DI ベースの NuGet パッケージがリリースされていたので、これを使うとサクッと組み込むことが出来ます。

Unity DI は最近アクティブに開発されているので良い感じです。

実際に ASP.NET Web Forms のプロジェクトを作成して確認してみました。

ポイントとしては Application_Start で DI の設定を行うぐらいで、後はコンストラクタインジェクションでインスタンスが受け取れます。

public class Global : System.Web.HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        var container = this.AddUnity();

        container.RegisterType<TestService>();
    }
}

型の登録時に LifetimeManager の設定も出来ますが、ASP.NET の場合はどれを使うべきか多少迷いますね。昔は PerRequestLifetimeManager を作ってましたが、デフォルトでまだ入っていないんですね。*2

登録してしまえば後はコンストラクタインジェクションで受け取れます。Page や UserControl 以外にも大体の部分で使えるみたいですが、基本的にはこの二つで使えれば問題ないでしょう。

public partial class Default : System.Web.UI.Page
{
    public Default(TestService testService)
    {
        _testService = testService;
    }

    private readonly TestService _testService;

    protected void Page_Load(object sender, EventArgs e)
    {
        label.Text = _testService.SayHello("buchizo");
    }
}

流石に IHttpModule とかで使うのはアンチパターンだと思いますし、使いたいケースもほぼないでしょう。

デバッガーを使って実際にインジェクションされるか確認しておきました。

f:id:shiba-yan:20181108152336p:plain

ちゃんと指定したクラスのインスタンスが渡されていることが確認出来ますね。

ちなみに HttpRuntime.WebObjectActivator を使って実装されてますが、必要な IServiceProvider の実装は少し面倒なので、用意されているパッケージのものを使うのが良いです。

f:id:shiba-yan:20181108153931p:plain

最後に App Service にデプロイして確認しておきました。ちゃんと動いてますね。

これまで .NET Framework 4.7.2 が使える PaaS はほぼ無かったので、今回のデプロイでようやく新機能を使うことが出来るようになって嬉しいです。

*1:数日中にアナウンスがあるとは思いますけど

*2:代替があるのかも知れないけど未確認