SourceChord

C#とXAML好きなプログラマの備忘録。最近はWPF系の話題が中心です。

.NET Coreことはじめ~その4・サーバーの各種設定~

今回は、Startupクラスの各種関数内で、色々なサーバーの設定をしてみたいと思います。

Startupクラスの各種メソッド

Startupクラスでは、コンストラクタとConfigureServecies, Configureメソッドなどで、サーバーの各種設定を行うことができます。

それぞれどんなことができるかは、追々見ていくこととして、まずはこれらのメソッドだけ作ってConsole.WriteLineを書き、実行時に呼び出されていることの確認だけをしておきます。

Startup.cs

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace aspnetcoreapp
{
    public class Startup
    {
        public Startup (IHostingEnvironment env)
        {
            Console.WriteLine("--Startup Constructor--");
        }

        public void ConfigureServices(IServiceCollection services)
        {
            Console.WriteLine("--ConfigureServices--");
        }
        
        public void Configure(IApplicationBuilder app)
        {
            Console.WriteLine("--Configure--");

            app.Run(context =>
            {
                return context.Response.WriteAsync("Hello World!!");
            });
        }
    }

}

f:id:minami_SC:20161030135024p:plain

Startupクラスの各種メソッドの引数

コンストラクタ、ConfigureServecies、Configureの各メソッドには、それぞれ以下のような引数を設定できるようになっています。

https://docs.asp.net/en/latest/fundamentals/startup.html#services-available-in-startup

こんな風に、いろんな引数を持ったメソッドとして定義できます。
その時々に応じて、必要な引数を追加して使うイメージなのかもしれません。

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory logger)
        {
            app.Run(context =>
            {
                return context.Response.WriteAsync("Hello World!!");
            });
        }

Development/Productionモード

WebサーバーをDevelopmentモード、Productionモードのどちらで動いているかに応じて、処理を切り替えることができます。

以下のように、IsDevelopment、IsProduction関数の結果を見ることで、それぞれのモードに応じて処理を切り替えることができます。

    public class Startup
    {
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            var message = "Hello World!!\n";
            if (env.IsDevelopment()){
                message += "(Development)";
            }

            if (env.IsProduction()){
                message += "(Production)";
            }

            app.Run(context =>
            {
                return context.Response.WriteAsync(message);
            });
        }
    }

どんなモードで動作するかは、Main関数でWebHostBuilderでUseEnvironment関数を呼び出すことで変更できます。
下のように、UseEnvironment("Production")と呼び出すと、Productionモードでの実行となります。 Program.cs

        public static void Main(string[] args)
        {
            var host = new WebHostBuilder().UseKestrel()
                                           .UseStartup<Startup>()
                                           .UseEnvironment("Production")
                                           .Build();

            host.Run();
        }

f:id:minami_SC:20161030135917p:plain

ログ出力

依存パッケージの追加

これらのログ出力機能を使うためには、"Microsoft.Extensions.Logging": "1.0.0" "Microsoft.Extensions.Logging.Console": "1.0.0"というパッケージを追加します。

project.jsonのdependenciesを以下のように修正し、dotnet restoreを実行します。

{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {
    "Microsoft.Extensions.Logging": "1.0.0",
    "Microsoft.Extensions.Logging.Console": "1.0.0"
  },

そして、ログを出力したい箇所で、以下のようにLogTraceなどのログ出力用メソッドを実行します。

Startup.cs

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

namespace aspnetcoreapp
{
    public class Startup
    {
        public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole((str, level) => {
                return level >= LogLevel.Trace;
            });

            var log = loggerFactory.CreateLogger("Startup");
            app.Run(context =>
            {
                log.("log trace test");
                log.LogWarning("log warning test");
                return context.Response.WriteAsync("Hello World!!");
            });
        }
    }
}

フレームワーク側のログも出力されますが、自分で追加したログも以下のようにコンソールに出力されるようになりました。
f:id:minami_SC:20161030135319p:plain

アプリのライフサイクルに伴うイベント

以下のようにConfigureメソッドに、IApplicationLifetime型の引数を追加すると、アプリ起動時や終了前などのタイミングで任意の処理を実行できるようになります。

↓のサンプルでは、アプリ起動時と終了前にログ出力をするようにしてみました。

        public void Configure(IApplicationBuilder app, IApplicationLifetime lifetime, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole((str, level) => {
                return level >= LogLevel.Trace;
            });
            var log = loggerFactory.CreateLogger("Startup");

            lifetime.ApplicationStarted.Register(() => log.LogTrace("--ApplicationStarted--"));
            lifetime.ApplicationStopping.Register(() => log.LogTrace("--ApplicationStopping--"));
            lifetime.ApplicationStopped.Register(() => log.LogTrace("--ApplicationStopped--"));

            app.Run(context =>
            {
                return context.Response.WriteAsync("Hello World!!");
            });
        }
    }

f:id:minami_SC:20161030135333p:plain