프로젝트를 한번 생성해서 개발을 하다가 새로운 버전의 프레임워크가 나오면, 속성에서 대상 프레임워크만 변경을 해주곤 했었는데요. 이런저런 테스트를 위해서 ASP.NET Core 6의 웹앱 템플릿을 새로 생성하는 과정에서 기존과는 다르게 Startup.cs 가 생성이 안되고, Configure 종속성도 보이질 않아서 찾아보던중에 최소 호스팅 모델에 대해서 알게되어 정리합니다. 추가로 ASP.NET Core 6 환경에서 지속적으로 사용하던 Startup 과 Configure 종속성 주입에 대해서도 같이 정리하였습니다.
1. 최소 호스팅 모델
ASP.NET Core 앱의 새 .NET 6 최소 호스팅 모델에는 파일 하나와 몇 줄의 코드만 필요합니다.
6.0으로 마이그레이션하는 앱은 새 최소 호스팅 모델을 사용할 필요가 없습니다.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
최소 호스팅 모델:
- 앱을 만드는 데 필요한 파일 수와 코드 줄이 대폭 줄어듭니다. 코드 4줄과 함께 파일이 하나만 있으면 됩니다.
- Startup.cs 및 Program.cs를 단일 Program.cs 파일로 통합합니다.
- 최상위 문을 사용하여 앱에 필요한 코드를 최소화합니다.
- 전역 using 지시문을 사용하여 필요한 using 문의 줄 수를 없애거나 최소화합니다.
2. ASP.NET Core 5 의 구성
ASP.NET Core 5 에서 프로젝트 생성시 아래와 같은 구성으로 템플릿이 생성이 되는데요.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
// Unused usings removed.
namespace WebAppRPv5
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}
}
Startup.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
// Unused usings removed.
namespace WebAppRPv5
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
Program.cs
Startup.cs와 Program.cs 파일이, ASP.NET Core 6 에서 아래의 형태의 코드로 대체 됩니다.
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
위의 ASP.NET Core 6 샘플에서는 다음 방법을 보여 줍니다.
- ConfigureServices가 WebApplication.Services로 바뀝니다.
- builder.Build()가 변수 app에 대해 구성된 WebApplication을 반환합니다. Configure는 app을 사용하여 동일한 서비스에 대한 구성 호출로 대체됩니다.
3. 최소 호스팅 모델에서 Startup 사용하기
namespace WebApp4
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
}
}
}
ASP.NET Core 6의 WebApplication 을 생성시 위와 같은 형태의 템플릿이 구성이 되는데요.
기존에 보아왔던 Startup.cs 파일은 더이상 생성 되지 않습니다.
ASP.NET Core 5에서 사용하던 Startup Class 를 지속적으로 사용하기 위해서는 추가 마이그레이션 작업을 진행해야하는데요.
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (!env.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStaticFiles();
}
}
프로젝트마다 구성은 다르겠지만, 기본적으로 위와같은 형태로 기존의 Startup Class 를 생성해 줍니다.
// Add services to the container.
var startup = new Startup(builder.Configuration);
startup.ConfigureServices(builder.Services);
그리고 위치는 다르겠지만, Startup Class 에 Configure 종속성을 수동으로 삽입해주면 되는데요.
이렇게 되면, 기존 ASP.NET Core 5 에서 사용하던 구성대로 ASP.NET Core 6 로 마이그레이션이 가능합니다.
4. ASP.NET Core 5 및 6 호스팅 모델의 차이점
- 개발 모드에서 개발자 예외 페이지 미들웨어는 기본적으로 사용하도록 설정되어 있습니다.
- 앱 이름은 기본적으로 진입점 어셈블리의 이름인 Assembly.GetEntryAssembly().GetName().FullName으로 지정됩니다. 라이브러리에서 WebApplicationBuilder를 사용하는 경우 앱 이름을 라이브러리의 어셈블리로 명시적으로 변경하여 MVC의 애플리케이션 파트 검색이 작동되도록 합니다.
- 엔드포인트 라우팅 미들웨어는 전체 미들웨어 파이프라인을 래핑하므로 경로를 등록하기 위해 UseRouting 또는 UseEndpoints에 대한 명시적 호출이 필요하지 않습니다. UseRouting은 경로 일치가 발생하는 위치를 지정하는 데 계속 사용할 수 있지만 미들웨어 파이프라인의 시작 부분에서 경로가 일치해야 하는 경우 UseRouting을 명시적으로 호출할 필요는 없습니다.
- 파이프라인은 IStartupFilter가 실행되기 전에 생성되므로 파이프라인을 빌드하는 동안 발생한 예외는 IStartupFilter 호출 체인에 표시되지 않습니다.
- EF 마이그레이션과 같은 일부 도구는 앱의 컨텍스트에서 사용자 지정 논리를 실행하기 위해 Program.CreateHostBuilder를 사용하여 앱의 IServiceProvider에 액세스합니다. 이러한 도구는 앱의 컨텍스트에서 사용자 지정 논리를 실행하는 데 새 기술을 사용하도록 업데이트되었습니다. 이런 식으로 Program.CreateHostBuilder를 사용하는 도구로 Entity Framework 마이그레이션이 있습니다. 새 모델을 사용하도록 도구가 업데이트되었는지 확인하고 있습니다.
- 클래스와 Startup 달리 최소 호스트는 서비스 공급자를 인스턴스화할 때 DI 범위를 자동으로 구성하지 않습니다. 범위가 필요한 컨텍스트의 경우 IServiceScopeFactory.CreateScope를 사용하여 호출 IServiceScope 하여 새 범위를 인스턴스화해야 합니다.
- WebApplicationBuilder를 만든 후에는 앱 이름, 환경 또는 콘텐츠 루트 같은 호스트 설정을 변경할 수 없습니다. 호스트 설정을 변경하는 방법에 대한 자세한 내용은 IHostBuilder 또는 IWebHostBuilder 사용자 지정을 참조하세요. 다음의 강조 표시된 API는 예외를 throw합니다.
참조
END
'.NET' 카테고리의 다른 글
[.NET 8] ASP.NET Core MVC 새 프로젝트 생성 시, /Views/Home/Index.cshtml 를 찾지 못하는 상황 수정 (2) | 2023.12.04 |
---|---|
[.NET Core] appsettings.json 파일을 각 개발환경에 맞게 사용하기 (0) | 2022.06.14 |
[ASP.NET Core] - JsonSerializer 이용 시 escape 하지 않는 방법 (0) | 2022.02.07 |
[ASP.NET Core] ASP.NET 5.0 타기팅 팩 오류 (1) | 2021.06.29 |
[ASP.NET] Task.Run() 이용 시 HttpContext 처리 (0) | 2021.03.19 |