WPF나 Windows Forms와 달리 아발로니아 디자인 타임은 코드 기반으로 렌더링하지 않고 빌드 산출물을 이용해서 디자인 타임을 구현하는 것 같습니다.
그래서 일반적인 빌드 환경에서는 AOT를 사용하지 않고, Publish 절차를 따로 두어서 그 때에만 NativeAOT 속성을 켜서 빌드하도록 컴파일 옵션을 명령줄 수준에서 변경하는 것을 채택하는 것이 개발하기에는 편한 것 같습니다.
그리고 더 깊게 들어가면, Program.cs 파일 내 Program 클래스에서 아래 메서드를 리플렉션으로 찾는 시도를 하는데 참조하는 과정에서 문제가 생기는 것 같습니다. 이것이 말씀하신 문제가 발생하는 원인으로 보입니다. (참고로 BuildAvaloniaApp 메서드의 리턴 타입과 파라미터 인자 목록, static 여부가 중요하고, public이든 private이든 찾는데는 문제가 없습니다.)
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
{
return AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace();
}
여담이지만, Avalonia를 Generic Host에 통합할 수 있는 방법을 찾기 위해서 코드를 테스트해보다가, 디자인 타임 프리뷰도 그대로 유지하고 싶어서 아래처럼 nudge를 적용하기도 했습니다. (식탁보 vNext에서 발췌)
[STAThread]
[SupportedOSPlatform("windows")]
private static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAvaloniauiDesktopApplication<App>(BuildAvaloniaApp);
using var app = builder.Build();
app.RunAvaloniauiApplication(args).GetAwaiter().GetResult();
}
// This method is used by both AppHost Avalonia runtime and the Avalonia Designer.
private static AppBuilder BuildAvaloniaApp(AppBuilder? app)
{
if (app == null)
app = AppBuilder.Configure<App>();
return app
.UsePlatformDetect()
.LogToTrace();
}
// This method is required for use with the Avalonia designer.
// The Avalonia designer will look for this method regardless of whether or not it is private.
private static AppBuilder BuildAvaloniaApp()
=> BuildAvaloniaApp(null);
말씀해주신 내용이 저도 궁금해서 찾아봤는데, 역시 코드베이스가 방대하다보니 Github Copilot으로도 몇 번의 문답이 필요한 것 같습니다. 아래는 GPT-5 Github Copilot 으로 정리한 내용입니다.
일단 디자이너가 사용할 화면을 불러오는 과정에서 쓰이는 코드는 아래 위치에 있는 것 같습니다.
다만 이것만으로 전체 동작이 설명되는 것은 아니고, 디자인 타임 호스트 프로세스, 익스텐션, IDE 사이를 프로세스 공간을 섞지 않기 위해서 굉장히 많은 계층과 그 사이의 통신을 BSON과 TCP 소켓 등을 사용해서 처리하고 있었습니다. (앞의 답글에서 리플렉션을 사용했다는 말에는 취소선을 그었습니다.)
다음은 “리플렉션만 쓰는 게 아니라 BSON 소켓 통신을 사용해 디자인-타임 미리보기(프리뷰)를 구현하는” 전체 아키텍처 설명입니다.
개요
IDE 확장(Visual Studio/VS Code)과 프리뷰어 호스트 프로세스(Avalonia.Designer.HostApp)가 별도 프로세스로 분리됩니다.
통신은 로컬 루프백(127.0.0.1)에서 TCP 소켓 위에 BSON 직렬화를 사용하는 프로토콜로 이뤄집니다.
사용자의 앱 초기화(BuildAvaloniaApp 호출)와 XAML 로드/렌더링은 호스트 프로세스에서 수행됩니다. IDE 프로세스는 호스트와 메시지를 주고받으며 비트맵 프레임과 오류만 수신/표시합니다.