.NET core 3 版:IServiceCollectionの拡張(ConfigureServicesのアレ)(WebApi ビルドの場合)

.NET Core2.2時代に、WebApi(REST)開発を行う際、.AddMvc()が差し込まれるのが辛かったので、必要なものだけを差すように書き直していたのですが、.NET Core 3(RC)版のIServiceCollectionの拡張を見たら、少し変わっていたので、中を確認してみました。

.NET Core2.2時代のMicrosoft.AspNetCore.Mvc [ MvcServiceCollectionExtensions ]

f:id:CreatioVitae:20190919130629p:plain
Core2.2

        public static IMvcBuilder AddMvc(this IServiceCollection services)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            var builder = services.AddMvcCore();

            builder.AddApiExplorer();
            builder.AddAuthorization();

            AddDefaultFrameworkParts(builder.PartManager);

            // Order added affects options setup order

            // Default framework order
            builder.AddFormatterMappings();
            builder.AddViews();
            builder.AddRazorViewEngine();
            builder.AddRazorPages();
            builder.AddCacheTagHelper();

            // +1 order
            builder.AddDataAnnotations(); // +1 order

            // +10 order
            builder.AddJsonFormatters();

            builder.AddCors();

            return new MvcBuilder(builder.Services, builder.PartManager);
        }

VisualStudio2019でスキャフォールディングされるコードでは、.AddMvc()を呼び出しますが、WebApiを構築する場合、色々要らないものがあるので、自分でメソッドを切る人が大半だったと思います。 自分が書く場合は、Viewに関するものは省いて、StaticFileも省いて、Cors設定書いて、JsonOutputFormatterをUTF8Jsonに差し直して……ってやることが多いです。

        public static IMvcCoreBuilder CreateDefaultBuilder(this IServiceCollection serviceDescriptors) {
            return serviceDescriptors
                .AddMvcCore()
                .AddApiExplorer()
                .AddAuthorization()
                .AddCors(option => { {Cors.PolicyName}, builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());})
                .AddDataAnnotations()
                .AddFormatterMappings()
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
                .AddMvcOptions(
                    option => {
                        option.OutputFormatters.Clear();
                        option.OutputFormatters.Add(new Utf8Json.AspNetCoreMvcFormatter.JsonOutputFormatter(StandardResolver.ExcludeNullCamelCase));
                        option.InputFormatters.Clear();
                        option.InputFormatters.Add(new Utf8Json.AspNetCoreMvcFormatter.JsonInputFormatter(StandardResolver.ExcludeNullCamelCase));

                    }
                );
        }

.NET Core3時代のMicrosoft.AspNetCore.Mvc [ MvcServiceCollectionExtensions ]

f:id:CreatioVitae:20190919152713p:plain
.NET Core3

.AddMvc()の他に、.AddControllers()、.AddControllersWithViews()、.AddRazorPages()が追加されています。 .AddControllers()の中ではAddControllersCore()というPrivateメソッドを呼んでいます。(このAddControllersCore()は.AddControllersWithViews()でも呼ばれてます。)

        public static IMvcBuilder AddControllers(this IServiceCollection services)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            var builder = AddControllersCore(services);
            return new MvcBuilder(builder.Services, builder.PartManager);
        }

        private static IMvcCoreBuilder AddControllersCore(IServiceCollection services)
        {
            // This method excludes all of the view-related services by default.
            return services
                .AddMvcCore()
                .AddApiExplorer()
                .AddAuthorization()
                .AddCors()
                .AddDataAnnotations()
                .AddFormatterMappings();
        }

WebApiをビルドする場合、.AddControllers()を呼ぶだけで、使い始められるくらい、必要なものだけ差し込まれてる印象です。 CorsやJsonOutputFormatterのセットアップは変わらず行う必要があるので、実際は結局色々書く気はするんですが、随分すっきりした印象ですね。素敵。