ASP.NET Coreでコマンドのオプションから処理分けしてみる

公開日:2019-01-04
最終更新:2019-01-04

どういう風に言っていいのかわからないという事は整理がついていないという事かもしれませんが・・・。

ASP.NET Coreのアプリ作成したときに初期化の処理だったり、ユーザーの追加だったりをコマンドから行いたいと思いませんか?
例えば

dotnet run -- adduser -U hogehoge -P hagehage

みたいな感じに。
当然この際にはWebサーバが起動せずコマンドだけ実行して終了という形にです。

今回はMcMaster.Extensions.CommandLineUtilsを使ってコマンドパラメータを取得しつつ処理分岐を行うという事をやってみました。

大枠として

今回作成したProgram.csは↓の通りです。(実際の処理は除く)

    public enum AppAction  
    {  
        server, init, adduser  
    }  

    public class Program  
    {  

        [Argument(0, Description = "処理(init=初期化, server=サーバー起動, adduser=ユーザー登録")]  
        private AppAction Action {get; set;}  

        [Option("-U|--user", Description="ユーザー名(email) - adduser")]  
        private string Email {get; set; }  

        [Option("-P|--password", Description="パスワード - adduser")]  
        private string Password {get; set;}  

        public static int Main(string[] args){  
            return CommandLineApplication.Execute<Program>(args);  
        }  
        private async Task OnExecute()  
        {  
            var server = CreateWebHostBuilder().Build();  

            switch(Action){  
                case AppAction.init:  
                    await InitializeApplication(server);  
                    break;  
                case AppAction.adduser:  
                    await AddUser(server);  
                    break;  

                case AppAction.server:  
                default:  
                    server.Run();  
                    break;  
            }  

        }  
    }

McMaster.Extensions.CommandLineUtilsについて

このパッケージを使うと、プロパティにアノテーションを設定することで自動的に指定されたオプションを設定してくれます。
またDescriptionを入力することでヘルプに説明が表示されるようになります。

 dotnet run -- --help

とすることで

Usage: hogeeee [arguments] [options]  

Arguments:  
  Action         処理(init=初期化, server=サーバー起動, adduser=ユーザー登録  

Options:  
  -U|--user      ユーザー名(email) - adduser  
  -P|--password  パスワード - adduser  
  -?|-h|--help   Show help information

といった形に自動でヘルプ表示をしてくれます。

各コマンドの処理について

この例では、init、adduser、そして通常のサーバー起動の3種類の処理があります。
あらかじめ CreateWebHostBuilder().Build();によりIWebHostのインスタンスを取得しておき、サーバ起動の必要があればRunメソッドを呼び出します(通常の処理)

それ以外に処理については、IWebHostインスタンスを渡してそれぞれの処理を行う形にしています。
例えばユーザー追加といったものは下記のように作成しました。

        private async Task AddUser(IWebHost server){  
            using (var scope = GetScope(server))  
            {  
                var userManager = scope.ServiceProvider.GetService<UserManager<ApplicationUser>>();  

                //パラメータ確認  
                if(String.IsNullOrWhiteSpace(Email) || String.IsNullOrWhiteSpace(Password)){  
                    Console.WriteLine("ユーザー名、パスワードが指定されていません");  
                    return;  
                }  
                Email = Email.Trim();  
                Password = Password.Trim();  

                //ユーザー存在確認  
                var user = await userManager.FindByEmailAsync(Email);  
                if(user != null){  
                    Console.WriteLine($"ユーザー{Email}はすでに登録されています");  
                    return;  
                }  

                //ユーザー作成  
                var ret = await userManager.CreateAsync(new ApplicationUser(){  
                    Email = Email,  
                    UserName = Email  
                }, Password);  

                if(!ret.Succeeded){  
                    Console.WriteLine("ユーザー作成に失敗しました");  
                    Console.WriteLine(String.Join("\n", ret.Errors.Select( x=>x.Description)));  
                }  


            }  
        }  

        private IServiceScope GetScope(IWebHost server) =>  
            ((IServiceScopeFactory)server.Services.GetService(typeof(IServiceScopeFactory))).CreateScope();

通常DIで取得するサービスについて

コントローラ等でDIを使い、取得するオブジェクトですが単純にserver.Services.GetServiceでは取得出来ないことが多いです。
理由についてはいまいち理解していませんが、一旦IServiceScopeFactoryを取得して、IServiceScopeを作成しそこから取得することが可能です。

その為、↑の例ではGetScope関数を作成して取得できるようにしています。後は取得したスコープから必要なオブジェクトをGetServiceで取得すれば使用することが可能です。

思ったこと

いつも思うのですがASP.NET Coreは思いのほか多機能で色々できるのですが、正式ドキュメントを見てもさっぱりわからないことが多く困ってしまいます(;´∀`)
いつも先人たちに助けられるのですが、バージョンアップで使えなくなったりと結構苦労することが多いです(ノД`)・゜・。

記事が少しでもいいなと思ったらクラップを送ってみよう!
0
+1
@saitooooの技術ブログ

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする