👻

ゆるやかに ASP.NET を ASP.NET Core に移行する

2024/11/16に公開

ゆるやかに ASP.NET を ASP.NET Core に移行する

ASP.NET Core が誕生してからだいぶたちました。しかし、過去の遺産の膨大さに途方に暮れ、なかなか移行できない現場も多いのではないでしょうか?

一気に移行するのはリスクも高いですし、その間機能追加がしづらくなる問題もあり、なかなかうまくいきません。少しずつゆるやかに移行することをお勧めします。

少しずつと言ってもいくつかの方法があります。

一つ目は、旧 ASP.NET のアプリケーションインスタンスとは別に ASP.NET Core のアプリケーションインスタンスを立ち上げ、リバースプロキシを利用して切り替える方式です。この方法は複数インスタンスの管理という面倒な点はあるものの、旧アプリケーションにトラブルが起きにくい利点があります。

二つ目は、ASP.NET Core アプリケーションインスタンスを立ち上げ、公式ドキュメントにあるASP.NET Core パイプラインで OWIN ミドルウェアを実行する を利用し、ASP.NET Core アプリケーションインスタンスの中で ASP.NET Owin を実行するものです。この方法はインスタンスは一つで済みますが、Owin 以外の ASP.NET MVC や ASP.NET WebForms などは動作しませんし、.NET (not Framework) では .NET Framework 専用で使えないクラスも出てきて一筋縄ではいかないかもしれません。

三つ目は Owin2AspNetCore を利用し、旧 ASP.NET のアプリケーションインスタンスの中で、Owin ミドルウェアとして ASP.NET Core アプリケーションを同居させる方法です。今動作している旧 ASP.NET のアプリケーションインスタンスにはほとんど手を入れませんので、旧アプリケーションにトラブルが起きにくい利点があります。また、アプリケーションインスタンスも今までと変えなくて済むため、構成情報や監視などはそのまま利用できます。

この方法のデメリットは次の通りです。

この三つ目の方法を紹介します。

Owin2AspNetCore で移行する

導入は簡単です。

まずは今開発している旧 ASP.NET アプリケーションに Owin2AspNetCore の参照を追加します。

そして Owin のスタートアップクラスに次のような処理を追加します。(もし、ASP.NET Owin が構成されていない場合は構成してください)

class OwinStartup
{
    public void Configuration(IAppBuilder app)
    {
        // `/core` 以下にアクセスした場合、ASP.NET Core を呼び出します。
        app.Map("/core", core =>
        {
            var aspNetCore = WebHost
                .CreateDefaultBuilder<AspNetCoreStartup>(Array.Empty<string>());
            core.UseAspNetCore(aspNetCore);
        });

        // 追加の ASP.NET Owin 構成。
    }
}

ASP.NET Core 2.1 アプリケーションに必要なスタートアップクラスを追加します。

class AspNetCoreStartup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // configure services...
    }
    
    public void Configure(IApplicationBuilder app)
    {
        app.Run(context => context.Response.WriteAsync("Hello! ASP.NET Core."));
    }
}

これだけです。/core 以下にアクセスしたときに Hello! ASP.NET Core. と表示されます。

あとは、ASP.NET Core 2.1 の流儀に従って、Web API のミドルウェアを追加したりしてください。たったこれだけです。

できれば、ASP.NET Core 部分は新しい Visual Studio プロジェクトを作成したほうがよいでしょう。そうしておけば、あとから一つ目として紹介した、リバースプロキシを使う方法への切り替えも難しくありません。

仕組み

ASP.NET Core には IServer というインターフェイスがあり、組み込みの Web サーバーの Ketrel はこれを実装した KestrelServer を利用しています。KestrelServer の中で、TCP でコネクションを待機し、HTTP プロトコルを受け付け、それを ASP.NET Core の HttpContext に変換して、ASP.NET Core アプリケーションパイプラインに投入しています。

Owin2AspNetCore はカスタム IServerOwin2AspNetCoreServer を経由して、Owin ミドルウェアから ASP.NET Core アプリケーションパイプラインに投入するようにしています。仕組み的にはとても単純です。

課題

Owin2AspNetCoreServer は Microsoft.AspNetCore.Owin を利用して、IOwinContext -> ASP.NET Core HttpContext への変換を行っています。ただし、あらゆるリクエストを処理できるわけではなく、動かないものもあります。発見次第修正していますので、不具合を見つけたら Issue を発行していただけると助かります。

近いうちに動作確認を行う予定のものは次の通りです。

  • ASP.NET Core MVC (の Razor View)
  • ASP.NET Core Razor Pages
  • WebSockets

最後に

今回紹介した Owin2AspNetCore は ASP.NET から ASP.NET Core への移行中に使える手段として、導入がとても簡単です。うまくいかなかったとしても紹介した一つ目や二つ目への構成変更は難しくありません。

あれこれ考えて一気に ASP.NET Core 化をすると、慣れないフレームワークに翻弄されて新たなレガシーコードを量産することになります。また、日常の仕事に忙殺され、なかなか手を付けられない間にレガシーの資産がどんどん増えていきます。

すぐに始められる Owin2AspNetCore で、まずは新機能の追加から ASP.NET Core で書き始めてみませんか?

Discussion