ASP.NET 및 ASP.NET Core 애플리케이션 간 코드 공유 전략

ASP.NET Core는 .NET 6 출시와 함께 더욱 강력해졌습니다. 기존 ASP.NET 애플리케이션을 ASP.NET Core로 마이그레이션하는 것은 상당한 노력이 필요해 보일 수 있지만, 점진적인 접근 방식을 통해 마이그레이션 과정을 훨씬 수월하게 만들 수 있습니다. 이 글에서는 기존 ASP.NET 프로젝트의 코드를 ASP.NET Core와 공유하여 향후 마이그레이션을 용이하게 하는 방법을 살펴봅니다.

데모 시나리오로 10년 된 ASP.NET MVC 애플리케이션의 코드를 ASP.NET Core와 공유하는 방법을 구체적으로 살펴보겠습니다. ASP.NET MVC 3의 "Music Store" 샘플 애플리케이션에서 ShoppingCartController.cs 파일을 ASP.NET Core 프로젝트로 가져오는 과정을 예시로 사용합니다.

마이그레이션의 첫 단계는 새로운 ASP.NET Core 웹 애플리케이션(Model-View-Controller) 프로젝트를 생성하는 것입니다. 이 템플릿은 컨트롤러 지원을 포함하며, Program.cs 파일에서 기본 라우팅을 설정합니다. 새 프로젝트 설정이 완료되면, 기존 MVC 3 프로젝트와의 충돌을 피하기 위해 기본 HomeController 및 관련 뷰 파일(Home/Index, Home/Privacy)을 삭제합니다.

컨트롤러 공유

두 프로젝트 간에 가장 먼저 공유할 수 있는 것은 컨트롤러입니다. 많은 경우, 기존 웹사이트와 동일한 기능을 새 웹사이트에서도 구현하고자 할 것입니다. 즉, 한 프로젝트에서 버그를 수정하면 다른 프로젝트에도 동일한 수정 사항이 적용되어야 합니다. 이를 보장하는 가장 간단한 방법 중 하나는 두 프로젝트에서 동일한 소스 코드를 사용하는 것입니다. 다행히 ASP.NET Core는 SDK 스타일 프로젝트 파일(.csproj)을 사용하므로, 프로젝트 파일을 쉽게 수정하여 기존 코드를 참조할 수 있습니다.

컨트롤러 클래스를 공유하려면, ASP.NET Core 프로젝트의 .csproj 파일에 <ItemGroup> 요소를 추가하고 기존 컨트롤러 파일에 대한 참조를 지정합니다. 다음은 ShoppingCartController.cs 파일을 공유하기 위한 .csproj 파일 수정 예시입니다.

<ItemGroup>
  <Compile Include="..\MvcMusicStore\Controllers\ShoppingCartController.cs" LinkBase="Controllers" />
</ItemGroup>

위와 같이 프로젝트 파일이 수정되면, ASP.NET Core 프로젝트가 컴파일되지 않는 문제가 발생할 수 있습니다. 이는 ASP.NET Core 컨트롤러가 System.Web.Mvc 대신 Microsoft.AspNetCore.Mvc 네임스페이스를 사용하기 때문입니다.

이 컴파일 오류를 해결하기 위해 ShoppingCartController.cs 파일을 다음과 같이 수정합니다. C# 전처리기 지시문(#if NET)을 사용하여 Microsoft.AspNetCore.MvcSystem.Web.Mvc 네임스페이스를 조건부로 포함시킬 수 있습니다.

#if NET
using Microsoft.AspNetCore.Mvc;
#else
using System.Web.Mvc;
#endif

// ... 컨트롤러 코드 ...

ShoppingCartController 내의 다른 부분도 마찬가지 방식으로 업데이트해야 할 수 있습니다. C# 전처리기 지시문을 활용하면 두 프로젝트 모두에서 컴파일될 수 있도록 클래스를 유연하게 만들 수 있습니다.

만약 코드베이스가 방대하고 ASP.NET Core와 기존 ASP.NET 간의 동작 방식 차이가 크다면, 구현별 파일을 생성하는 것이 좋습니다. 부분 클래스(partial class)를 사용하여 해당 코드 블록을 분리하고, .csproj 파일에서 빌드 시 포함될 파일을 제어하는 방식을 사용할 수 있습니다.

모델 공유

컨트롤러 공유가 가능해지면, 컨트롤러에서 반환하는 모델도 공유할 수 있습니다. 대부분의 경우, .csproj 파일에 <itemgroup>을 추가하여 모델 파일을 포함시키는 것만으로도 작동합니다. 하지만 모델이 System.Web을 참조하는 경우, 컨트롤러에서 사용했던 동일한 전처리기 지시문 방식을 적용하여 네임스페이스를 업데이트해야 합니다.

다음은 Order 클래스에서 [Bind] 속성을 수정하는 예시입니다. [ScaffoldColumn(false)] 속성과 [BindNever] 속성도 마찬가지로 조건부로 처리할 수 있습니다.

// ... 다른 네임스페이스 선언 ...

public partial class Order
{
    [ScaffoldColumn(false)]
#if NET
    [BindNever]
#endif
    public int OrderId { get; set; }

#if !NET
    [Bind(Exclude = "OrderId")]
#endif
    // ... 나머지 속성 ...
}

뷰 공유

뷰 파일도 공유할 수 있습니다. .csproj 파일에 뷰 파일(_Layout.cshtml 등)에 대한 참조를 추가하여 공유할 수 있습니다. 뷰 파일 내부에서도 C# 전처리기 지시문을 사용하여 두 프로젝트 모두에서 작동하도록 코드를 유연하게 만들 수 있습니다.

다음은 ASP.NET의 @Html.RenderAction과 ASP.NET Core의 @await Component.InvokeAsync를 혼합하여 사용하는 마스터 페이지 예시입니다. 이를 통해 카트의 상품 수를 보여주는 뷰의 일부를 렌더링할 수 있습니다.

@{
    #if NET
        <text>@await Component.InvokeAsync("CartSummary")</text>
    #else
        @Html.RenderAction("CartSummary", "ShoppingCart");
    #endif
}

정적 콘텐츠 및 기타 자원

CSS, JavaScript, 이미지와 같은 정적 콘텐츠 역시 공유할 수 있습니다. 이러한 점진적인 코드 유연성 확보는 ASP.NET Core로의 마이그레이션을 더욱 용이하게 만듭니다.

GitHub의 MvcMusicStoreMigration 저장소에서 ShoppingCartController.cs 전체를 마이그레이션하는 상세한 가이드와 예제를 확인할 수 있습니다. 또한, 동일한 IIS 애플리케이션 풀에서 ASP.NET과 ASP.NET Core를 함께 실행하여 웹 애플리케이션을 점진적으로 마이그레이션하는 방법을 보여줍니다.

ASP.NET Core 마이그레이션을 계획 중인 분들을 위해 몇 가지 추가 팁을 공유합니다.

  • netstandard를 활용하기 위해 NuGet 패키지를 최신 버전으로 업그레이드합니다.
  • ASP.NET과 ASP.NET Core 간에 코드를 공유하려면 클래스 라이브러리를 netstandard 대상으로 변경합니다.
  • 클래스 라이브러리에서 System.Web에 대한 참조를 인터페이스로 대체하고 의존성 주입(Dependency Injection)을 활용하여 ASP.NET과 ASP.NET Core 기능 간 전환을 쉽게 만듭니다.

ASP.NET에서 ASP.NET Core로 마이그레이션하는 방법에 대한 추가적인 지침은 공식 문서를 참조하십시오.

태그: ASP.NET ASP.NET Core 코드 공유 마이그레이션 C#

8월 3일 04:11에 게시됨