programing

View Model Locator란 무엇이며 Data Templates와 비교한 장점은 무엇입니까?

megabox 2023. 4. 9. 21:19
반응형

View Model Locator란 무엇이며 Data Templates와 비교한 장점은 무엇입니까?

ViewModelLocator의 개요, 작동 방식 및 DataTemplates와 비교하여 ViewModelLocator를 사용할 때의 장단점을 간단히 설명해 주시겠습니까?

구글에서 정보를 찾아봤지만, 구현은 여러 가지가 있는 것 같고, 어떤 것인지와 사용의 장단점에 대한 스트라이그 리스트는 없는 것 같습니다.

도입부

MVVM에서는 View가 의존성 주입(DI) 컨테이너에서 View Model을 해결함으로써 View Model을 검색하도록 하는 것이 일반적입니다.이 문제는 컨테이너가 View 클래스의 인스턴스를 제공(해결)하도록 요청될 때 자동으로 발생합니다.컨테이너는 ViewModel 파라미터를 받아들이는 View의 컨스트럭터를 호출하여 ViewModel을 View에 주입합니다.이 방식을 IoC(Inversion of Control)라고 부릅니다.

DI의 이점

여기서 가장 큰 장점은 컨테이너에서 요청한 유형을 해결하는 방법에 대한 지침을 사용하여 런타임에 컨테이너를 구성할 수 있다는 것입니다.이를 통해 어플리케이션이 실제로 실행될 때 사용하는 유형(Views 및 View Models)을 해결하도록 지시하고 어플리케이션의 유닛 테스트를 실행할 때는 다르게 지시함으로써 테스트 가능성을 높일 수 있습니다.후자의 경우 응용 프로그램에는 UI(실행 중이 아니라 테스트 중임)조차 없기 때문에 컨테이너는 응용 프로그램 실행 시 사용되는 "일반" 유형 대신 모크를 해결합니다.

DI에 기인하는 문제

지금까지 DI 접근방식은 애플리케이션 컴포넌트 작성에 추상화 레이어를 추가함으로써 애플리케이션에 대한 간단한 테스트성을 제공합니다.이 접근법에는 한 가지 문제가 있습니다. Microsoft Expression Blend와 같은 비주얼 디자이너와 잘 어울리지 않습니다.

문제는 일반 응용 프로그램 실행과 장치 테스트 실행 모두에서 해결할 유형에 대한 지침을 사용하여 컨테이너를 설정해야 한다는 것입니다. 또한 ViewModel을 해당 컨테이너에 주입할 수 있도록 View를 해결하도록 컨테이너에 요청해야 합니다.

그러나 디자인 타임에는 실행 코드가 없습니다.설계자는 반사를 사용하여 보기 인스턴스를 작성하려고 합니다. 즉, 다음과 같습니다.

  • View 생성자에 ViewModel 인스턴스가 필요한 경우 설계자는 View를 인스턴스화할 수 없습니다. 제어된 방식으로 오류가 발생합니다.
  • 가 없는 뷰는 인스턴스화됩니다.DataContext 되다null에서 ' 뷰가 가 없어요. 이것은 그다지 유용하지 않습니다.

View Model Locator 를 입력합니다.

View Model Locator는 다음과 같이 사용되는 추가 추상화입니다.

  • View 자체는 ViewModelLocator를 리소스의 일부로 인스턴스화하고 DataContext를 로케이터의 ViewModel 속성에 바인딩합니다.
  • 로케이터는 우리가 디자인 모드인지 아닌지를 감지한다.
  • 설계 모드가 아닌 경우 로케이터는 위에서 설명한 바와 같이 DI 컨테이너에서 해결한 ViewModel을 반환합니다.
  • 설계 모드인 경우 로케이터는 자체 논리를 사용하여 고정된 "더미" ViewModel을 반환합니다(설계 시간에는 컨테이너가 없습니다).; 이 View Model은 일반적으로 더미 데이터로 미리 채워져 있습니다.

물론 이는 보기에 매개변수 없는 생성자가 있어야 함을 의미합니다(그렇지 않으면 설계자가 이를 인스턴스화할 수 없습니다).

요약

View Model Locator는 DI의 장점을 MVVM 어플리케이션에서 유지하면서 코드를 비주얼 디자이너와 잘 재생할 수 있는 관용어입니다.이를 응용 프로그램의 "Blendability"(표현식 혼합)라고 부르기도 합니다.

위의 내용을 요약한 후 여기에서 실제 를 참조하십시오.

마지막으로 데이터 템플릿을 사용하는 것은 ViewModelLocator를 사용하는 방법이 아니라 UI의 일부에 대해 명시적인 View/ViewModel 쌍을 사용하는 방법입니다.데이터 템플릿을 대신 사용할 수 있으므로 ViewModel에 대한 보기를 정의할 필요가 없는 경우가 종종 있습니다.

@John의 답변 구현 예시

뷰 모델 로케이터 클래스가 있습니다.각 속성은 뷰에 할당할 뷰 모델의 인스턴스가 됩니다., 동작하고 있지 할 수 .DesignerProperties.GetIsInDesignMode디자인할 때는 모의 모델을 사용하고, 애플리케이션을 실행할 때는 실제 오브젝트를 사용할 수 있습니다.

public class ViewModelLocator
{
    private DependencyObject dummy = new DependencyObject();

    public IMainViewModel MainViewModel
    {
        get
        {
            if (IsInDesignMode())
            {
                return new MockMainViewModel();
            }

            return MyIoC.Container.GetExportedValue<IMainViewModel>();
        }
    }

    // returns true if editing .xaml file in VS for example
    private bool IsInDesignMode()
    {
        return DesignerProperties.GetIsInDesignMode(dummy);
    }
}

그리고 사용하기 위해 로케이터를 에 추가할 수 있습니다.App.xaml자원:

xmlns:core="clr-namespace:MyViewModelLocatorNamespace"

<Application.Resources>
    <core:ViewModelLocator x:Key="ViewModelLocator" />
</Application.Resources>

그런 다음 뷰(예: MainView.xaml)를 뷰 모델에 배선하려면 다음 절차를 따릅니다.

<Window ...
  DataContext="{Binding Path=MainViewModel, Source={StaticResource ViewModelLocator}}">

이 질문의 다른 답변이 왜 디자이너와 관련된 것인지 이해할 수 없습니다.

View Model Locator의 목적은 View가 이를 인스턴스화할 수 있도록 하는 것입니다(예, View Model Locator = View First).

public void MyWindowViewModel(IService someService)
{
}

이것뿐만이 아닙니다.

public void MyWindowViewModel()
{
}

다음과 같이 선언합니다.

DataContext="{Binding MainWindowModel, Source={StaticResource ViewModelLocator}}"

어디에ViewModelLocatorIOC를 참조하는 클래스입니다.이것이 IOC의 문제를 해결하는 방법입니다.MainWindowModel공개하는 자산입니다.

뷰에 Mock 뷰 모델을 제공하는 것과는 관계가 없습니다.그걸 원하면 그냥 해

d:DataContext="{d:DesignInstance MockViewModels:MockMainWindowModel, IsDesignTimeCreatable=True}"

View Model Locator는 Unity와 같은 Control 컨테이너의 일부(임의) 반전 래퍼입니다.

참조처:

언급URL : https://stackoverflow.com/questions/5462040/what-is-a-viewmodellocator-and-what-are-its-pros-cons-compared-to-datatemplates

반응형