2022. 6. 24. 15:30

기본템플릿에는 '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'의 기능들을 찾아서~

사라진 '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 추가

최상위문을 난발하면 안 되겠네요.

다른 프로젝트에서 참조하려면 최상위문으로 선언된 개체들은 찾을 방법이 없습니다.

네임스페이스를 지정할 수 없기 때문입니다.

 

테스트나 빠르게 작성하여 사용할 목적에는 맞지만 복잡한 프로젝트에는 계획적으로 사용해야 할듯합니다.