기본템플릿에는 'startup.cs'가 없습니다.
모든 기능이 'Program.cs'하나로 작동할 수 있도록 구성되어 있습니다.
덕지덕지 연결된 구성을 간단하게 코드 몇 줄로 구성할 수 있도록 한 것입니다.
(참고 : Andrew Lock | .NET Escapades - Comparing WebApplicationBuilder to the Generic Host )
'Program.cs'에서 'Startup.cs'로 진입하는 구조는 왜 저런 구조가 되었는지를 이해하지 않으면 쓸데없이 파일만 2개로 나눈 듯한 느낌을 받게 되죠.
이렇게 기존 구조가 제거된 구문을 '최 상위문(top-level statements)'이라고 합니다.
(참고 : MS Learn - 자습서: 배우는 동안 최상위 문을 사용하여 코드를 빌드하는 아이디어 탐색 )
자동으로 코드를 생성해주니 잘 못 느끼긴 하지만 잡다한 구성들에 의한 성능 차가 있다고는 하는데.....
그게 크게 의미가 있을지 모르겠네요.
사라진 'Startup.cs'의 기능은 그대로 'Program.cs'에 구현이 가능합니다.
'ASP.NET Core 6'으로 새로 생성한 템플릿을 보면 'Program.cs'에 'Startup.cs'의 기능이 그대로 보입니다.
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();
기존 템플릿에 익숙한 사용자라면 'Program.cs'에 구분도 없이 마구 때려 넣는 방식이 마음에 들지 않을 겁니다.
다행히 기존 스타일도 그대로 사용할 수 있습니다.
(참고 : Andrew Lock | .NET Escapades - Upgrading a .NET 5 "Startup-based" app to .NET 6)
아래는 'ASP.NET Core 5'가 생성한 기본 템플릿입니다.
이 템플릿을 그대로 'ASP.NET Core 6'에 넣어도 작동합니다.
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>();
});
}
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.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApplication2", Version = "v1" });
});
}
// 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();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApplication2 v1"));
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
어떤 걸 사용해도 됩니다!
콘솔(Console) 프로젝트도 그렇고 직관적 코드 스타일을 지원하기 위해 다양한 형식을 지원하는구나....라는 생각이 듭니다.
문제는 이 직관적이라는 게 유지보수 측면에서는 환영하기만 하기 힘든 게 많습니다.
각 구성의 분류를 하기 위해서 주석에 의존해야 한다던가,
사용하는 기능과 미들웨어가 늘어나면 코드량도 늘어날 텐데 구분하기 힘들다던가 등등.
그래도 마이크로 소프트는 하위호환을 잘해주니 이전 스타일을 그대로 쓸 수 있다는 게 다행이라고 할 수 있죠 ㅎㅎㅎ
- 2022-10-12 추가
최상위문을 난발하면 안 되겠네요.
다른 프로젝트에서 참조하려면 최상위문으로 선언된 개체들은 찾을 방법이 없습니다.
네임스페이스를 지정할 수 없기 때문입니다.
테스트나 빠르게 작성하여 사용할 목적에는 맞지만 복잡한 프로젝트에는 계획적으로 사용해야 할듯합니다.