Share via


MetadataUpdateHandler를 사용하여 .NET 핫 다시 로드 확장(C#, Visual Basic)

캐시를 지우거나 UI를 새로 고쳐야 하는 코드 변경과 같이 일반적으로 지원되지 않는 추가 시나리오에 대한 .NET 핫 다시 로드 지원을 프로그래밍 방식으로 확장할 수 있습니다. 예를 들어 JSON 직렬 변환기를 사용하여 핫 다시 로드를 지원하려면 형식이 수정될 때 캐시를 지워야 합니다. .NET MAUI 개발자의 경우 생성자 편집이나 UI 요소에 대한 이벤트 처리기 등 정상적인 조건에서 핫 다시 로드를 트리거하지 않는 편집/업데이트에 대해 핫 다시 로드를 확장해야 할 수 있습니다. MetadataUpdateHandlerAttribute를 사용하여 애플리케이션 상태를 새로 고치거나, UI를 다시 렌더링하거나, 유사한 작업을 수행할 수 있습니다.

이 특성에 의해 지정된 형식은 다음 중 하나 이상의 서명과 일치하는 정적 메서드를 구현해야 합니다.

static void ClearCache(Type[]? updatedTypes)
static void UpdateApplication(Type[]? updatedTypes)

ClearCache는 업데이트 처리기에서 애플리케이션의 메타데이터에 따라 유추되는 모든 캐시를 지울 수 있는 기회를 제공합니다. 모든 ClearCache 메서드가 호출된 후에 UpdateApplication는 메서드를 지정하는 모든 처리기에 대해 호출됩니다. UI를 새로 고치는 데 UpdateApplication를 사용할 수 있습니다.

예시

다음 예제에서는 처음에 핫 다시 로드를 지원하지 않지만 MetadataUpdateHandler 구현 후 기능을 지원하는 .NET MAUI 프로젝트에 대한 시나리오를 보여 줍니다.

.NET 핫 다시 로드 테스트

  1. Visual Studio에서 새로운 .NET MAUI 프로젝트를 만듭니다. .NET MAUI 앱 프로젝트 템플릿을 선택합니다.

  2. App.xaml.cs에서 MainPage를 만드는 코드를 다음 코드로 바꿉니다.

    //MainPage = new MainPage(); // Template default code
    MainPage = new NavigationPage(new MainPage());
    

    다음으로, C#에서 UI 업데이트를 간소화하는 Build 메서드를 구현합니다. 이 메서드는 ContentPage.Content를 설정하고 페이지의 OnNavigatedTo에서 호출됩니다. OnNavigatedTo 이벤트는 셸 또는 NavigationPage 내에서 호스트되어야 합니다.

  3. MainPage.xaml.cs에서 MainPage 생성자 코드를 다음 코드로 바꿉니다.

    public MainPage()
    {
       InitializeComponent();
       Build();
    }
    
    void Build() => Content =
       new Label
       {
          Text = "First line\nSecond line"
       };
    
    protected override void OnNavigatedTo(NavigatedToEventArgs args)
    {
       base.OnNavigatedTo(args);
       Build();
    }
    
  4. F5 키를 눌러 앱을 시작합니다.

  5. 페이지가 로드된 후 C# 코드의 레이블 텍스트를 "First line\nSecond line\nThird line"으로 변경합니다.

  6. 핫 다시 로드Screenshot of the Hot Reload button. 단추를 선택합니다.

    업데이트된 텍스트가 실행 중인 앱에 표시되지 않습니다. 기본적으로 이 시나리오에 대한 핫 다시 로드 지원은 없습니다.

    Screenshot of Hot Reload not working.

MetadataUpdateHandler 추가

.NET MAUI 앱에서는 코드를 변경한 후 C# UI 코드를 다시 실행하기 위해 작업을 수행해야 합니다. UI 코드가 C#으로 작성된 경우 MetadataUpdateHandlerUpdateApplication 메서드를 사용하여 UI를 다시 로드할 수 있습니다. 이를 설정하려면 다음 코드를 사용하여 애플리케이션에 HotReloadService.cs를 추가합니다.

#if DEBUG
[assembly: System.Reflection.Metadata.MetadataUpdateHandlerAttribute(typeof(YourAppNamespace.HotReloadService))]
namespace YourAppNamespace { 
    public static class HotReloadService
    {
        #pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
        public static event Action<Type[]?>? UpdateApplicationEvent;
        #pragma warning restore CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

        internal static void ClearCache(Type[]? types) { }
        internal static void UpdateApplication(Type[]? types) {
            UpdateApplicationEvent?.Invoke(types);
        }
    }
}
#endif

대상으로 지정하는 페이지의 네임스페이스로 YourAppNamespace를 바꿔야 합니다.

이제 이전 코드가 추가되면서 Visual Studio에서 라이브 코드를 편집할 때 메타데이터 변경이 발생하고 앱이 UpdateApplicationEvent를 디스패치합니다. 따라서 이벤트를 등록하고 UI 업데이트를 수행하는 코드를 추가해야 합니다.

참고 항목

이 시나리오에서는 XAML 핫 다시 로드를 사용하도록 설정해야 합니다.

MainPage.xaml.cs에서 OnNavigatedTo 이벤트에서 UpdateApplicationEvent 이벤트 처리기를 등록하는 코드를 추가합니다.

protected override void OnNavigatedTo(NavigatedToEventArgs args)
    {
        base.OnNavigatedTo(args);

        Build();

#if DEBUG
        HotReloadService.UpdateApplicationEvent += ReloadUI;
#endif
    }

OnNavigatedFrom에서 이벤트 처리기를 구독 취소한 다음 이벤트를 처리하는 코드를 추가하고 Build 호출을 다시 실행합니다.

protected override void OnNavigatedFrom(NavigatedFromEventArgs args)
   {
   base.OnNavigatedFrom(args);

#if DEBUG
   HotReloadService.UpdateApplicationEvent -= ReloadUI;
#endif
    }

private void ReloadUI(Type[] obj)
{
   MainThread.BeginInvokeOnMainThread(() =>
   {
      Build();
   });
}

이제 앱을 시작합니다. C# 코드에서 레이블 텍스트를 변경하고 핫 다시 로드 단추를 누르면 UI가 새로 고쳐집니다!

Screenshot of Hot Reload working.