[アップデート] AWS Microservice Extractor for .NET の抽出機能のサポートされるプロジェクトタイプで ASP​.NET Web Forms と WCF がサポートされていました

2023.01.17

いわさです。

AWS では .NET ワークロードのマイグレーションやモダナイゼーションをサポートする様々なツールが提供されています。
その中のひとつ「AWS Microservice Extractor for .NET」ではレガシーな .NET アプリケーションからサービスの分析と抽出を支援するツールです。

これまで DevelopersIO でも数回紹介しました。

これまでは Microservice Extractor for .NET は移行元が ASP.NET MVC でのみ抽出をサポートしていました。
本日時点のドキュメントでも以下のように記述されていました。

Microservice Extractor supports analysis of C# source code. Extraction is supported for only ASP.NET MVC applications.

Supported use cases - AWS Microservice Extractor for .NET より

しかし、2022 年 11 月にどうやらツールがアップデートされており、Web Forms と WCF も抽出機能が使えるようになったようです。

個人的には MVC よりももっとレガシーな Web Forms のほうが移行負担高そうだなと思っていたので嬉しいアップデートな気がします。

.NET on AWS 的でいうと、ビジネスロジックを切り出して .NET Core への移行を行って ECS on Fargate や App Runner などでホストし、薄くなったプレゼンテーションレイヤーは Blazor WebAssembly に頑張って移行して CloudFront + S3 で配信するというアプローチあたりが良さそうですが、そのあたりの移行プロセスの一部をツールで自動化出来そうです。

また、ASP.NET Web Forms であれば Porting Assitant for .NET を使って Blazor Server へのコンバートに挑戦してみるという選択肢もあります。

今回は ASP.NET Web Forms を用意して Microservice Extractor for .NET を使い、一部の処理をサービスとして切り出してみました。

移行元アプリを用意

移行元アプリケーションは Visual Studio 2022 で ASP.NET Web Forms プロジェクトを新規作成します。

適当なページに以下のようにテキストボックスとボタンを配置します。

About.aspx

<%@ Page Title="About" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="About.aspx.cs" Inherits="hoge0117webform.About" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2><%: Title %>.</h2>
    <h3>Your application description page.</h3>
    <p>Use this area to provide additional information.</p>
    <asp:TextBox runat="server" ID="txtHoge">aaa</asp:TextBox>
    <asp:Button runat="server" ID="btnHoge" Text="hoge" OnClick="btnHoge_Click" />
</asp:Content>

そしてボタンが押されたタイミングでビジネスロジックを想定したメソッドをコールして入力文字列を加工(ここでは大文字に変換)するような実装を行ってみましょう。

About.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace hoge0117webform
{
    public partial class About : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void btnHoge_Click(object sender, EventArgs e)
        {
            var hogeService = new Hoge.HogeService();
            txtHoge.Text = hogeService.GetHogeText(txtHoge.Text);
        }
    }
}

HogeService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace hoge0117webform.Hoge
{
    public class HogeService
    {
        public HogeService()
        {
            //hoge
        }

        public string GetHogeText(string input)
        {
            return input.ToUpper();
        }
    }
}

簡易的ですが、この変換処理をサービスとして抽出してみます。

Microservice Extractor for .NET で Web Forms プロジェクトを読み込んで抽出

ツールの使い方自体は冒頭の紹介記事を見て頂くとして、ここでは Web Forms プロジェクトを実際に読み込んで、抽出まで出来ることを確認してみましょう。

アプリケーションのオンボーディングで問題なくプロジェクトを読み込むことが出来ました。

先程の HogeService クラスをグループ化して抽出と変換まで行います。

利用側は HTTP エンドポイントで利用するオプションを使いましょう。

問題なく変換されると思いますので、まずは呼び出し側のコードを見ましょう。
以下のようにサービスエンドポイントを経由して外部のビジネスロジックを呼び出すようにコードが変換されていますね。

About.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using hoge0117webform.EndpointAdapter;

namespace hoge0117webform
{
    public partial class About : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void btnHoge_Click(object sender, EventArgs e)
        {
            IHogeServiceEndpoint hogeService = HogeServiceEndpointFactory.GetEndpointAdapter();
            txtHoge.Text = hogeService.GetHogeText(txtHoge.Text);
        }
    }
}

また、対象として指定したクラスは .NET 6 の別プロジェクトとして抽出されており、MVC のコントローラーを中継して利用する形になっています。

HogeServiceController.cs

using System;
using Newtonsoft.Json;
using System.Web.Http.Description;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using hoge0117webform.Hoge;
using Microsoft.AspNetCore.Mvc;

namespace hoge0117webform.Controllers
{
    /* Added by CTA: RoutePrefix attribute is no longer supported */
    [RoutePrefix("api/HogeService")]
    [ApiController]
    public class HogeServiceController : ControllerBase
    {
        [Route("GetHogeText_473287f8")]
        [ResponseType(typeof(string))]
        [HttpPost]
        public IActionResult GetHogeText_473287f8Wrapper(dynamic endpointContainer)
        {
            try
            {
                dynamic ctorContainer = EndpointParamStore.GetConstructorContainer(endpointContainer);
                dynamic methodContainer = EndpointParamStore.GetMethodContainer(endpointContainer);
                HogeService myInstance = null;
                string ctorParamHash = EndpointParamStore.GetConstructorParamHash(ctorContainer);
                // Initialize the right constructor
                if (ctorParamHash.Equals("e3b0c442"))
                {
                    myInstance = new HogeService();
                }

                // Retrieve Method parameters
                string input = methodContainer.input;
                return Ok(myInstance.GetHogeText(input));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return InternalServerError(e);
            }
        }
    }
}

移行されたコードはリファクタリングしたい部分もありますが、冗長な手作業が一部ツールで自動化出来る点は大きいので評価の価値はありそうです。

さいごに

本日は AWS Microservice Extractor for .NET の移行元プロジェクトタイプで ASP​.NET Web Forms と WCF がサポートされていたので、実際に ASP​.NET Web Forms で抽出を試してみました。

ASP.NET Web Forms からの抽出を実際に利用出来ることが確認出来ました。
クラスが別ファイルになっていなければならないなどのツールで抽出にあたっての既存の制限事項はあるのですが、ASP.NET Web Forms や WCF からの移行計画を控えている方は、是非こういったツールのサポート範囲が広がっていっていることも知っておくと活用出来る時があるかもしれません。