Programming

ViewModelLocator는 무엇이며 DataTemplate과 비교하여 장단점이 무엇입니까?

procodes 2020. 8. 3. 17:55
반응형

ViewModelLocator는 무엇이며 DataTemplate과 비교하여 장단점이 무엇입니까?


누군가가 ViewModelLocator의 정의, 작동 방식 및 DataTemplates와 비교하여 사용하는 장단점에 대해 간략하게 요약 할 수 있습니까?

Google에서 정보를 찾으려고 시도했지만 정보의 구현 및 사용에 대한 장단점에 대한 많은 다른 구현이 있으며 엄격한 목록이없는 것 같습니다.


소개

MVVM에서 일반적인 관행은 뷰가 의존성 주입 (DI) 컨테이너 에서이를 해결하여 ViewModel을 찾도록하는 것입니다 . 이것은 컨테이너가 View 클래스의 인스턴스를 제공 (해결)하도록 요청 될 때 자동으로 발생합니다. 컨테이너 는 ViewModel 매개 변수를 허용하는 View 생성자를 호출하여 ViewModel을 View에 주입 합니다. 이 체계를 IoC ( Inversion of Control )라고 합니다.

DI의 장점

여기서 주요 이점은 요청한 유형을 해결하는 방법에 대한 지침과 함께 런타임에 컨테이너를 구성 할 수 있다는 것입니다. 따라서 응용 프로그램이 실제로 실행될 때 사용하는 유형 (Views 및 ViewModels)을 해결하도록 지시하지만 응용 프로그램에 대한 단위 테스트를 실행할 때 다르게 지시함으로써 테스트 가능성을 높일 수 있습니다. 후자의 경우 응용 프로그램에는 UI가 없으며 (실행되지 않고 테스트 만 있음) 컨테이너는 응용 프로그램이 실행될 때 사용되는 "일반"유형 대신 모의 객체해결 합니다.

DI에서 비롯된 문제

지금까지 우리는 DI 접근 방식으로 응용 프로그램 구성 요소 생성에 추상화 계층을 추가하여 응용 프로그램을 쉽게 테스트 할 수 있음을 확인했습니다. 이 방법에는 한 가지 문제가 있습니다 . Microsoft Expression Blend와 같은 시각 디자이너에게는 적합하지 않습니다 .

문제는 정상적인 응용 프로그램 실행과 단위 테스트 실행 모두 에서 해결해야 할 유형에 대한 지침으로 컨테이너 설정해야 한다는 것입니다. 또한 누군가가 ViewModels를 주입 할 수 있도록 컨테이너에게 Views 를 확인 하도록 요청 해야합니다.

그러나 디자인 타임에는 실행중인 코드가 없습니다 . 디자이너는 리플렉션을 사용하여 뷰의 인스턴스를 만들려고 시도합니다.

  • View 생성자에 ViewModel 인스턴스가 필요한 경우 디자이너는 View를 전혀 인스턴스화 할 수 없습니다. 제어 된 방식으로 오류가 발생합니다.
  • 보기는 매개 변수가없는 생성자가있는 경우보기 인스턴스화 될 것입니다,하지만이 DataContext될 것입니다 null우리가 '디자이너의 "빈"보기 얻을 것이다 - 그래서 매우 유용하지 않다

ViewModelLocator 입력

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

  • View 자체는 리소스의 일부로 ViewModelLocator를 인스턴스화 하고 DataContext를 로케이터의 ViewModel 속성에 데이터 바인딩합니다.
  • 로케이터는 어떻게 든 디자인 모드에 있는지 감지합니다.
  • 디자인 모드가 아닌 경우 로케이터는 위에서 설명한 바와 같이 DI 컨테이너에서 해석되는 ViewModel을 리턴합니다.
  • 디자인 모드에서 로케이터는 자체 로직을 사용하여 고정 된 "더미"ViewModel을 반환합니다 (기억 : 디자인 타임에 컨테이너가 없습니다!). 이 ViewModel은 일반적으로 더미 데이터로 미리 채워져 있습니다.

물론 이것은 뷰에 매개 변수가없는 생성자가 있어야 함을 의미합니다 (그렇지 않으면 디자이너가이를 인스턴스화 할 수 없음).

요약

ViewModelLocator는 MVVM 응용 프로그램에서 DI의 이점을 유지하면서 코드가 시각적 디자이너와 잘 재생되도록하는 관용구입니다. 이를 응용 프로그램의 "혼합 성"이라고도합니다 (Expression Blend 참조).

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

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


@ Jon 's answer 예제 구현

뷰 모델 로케이터 클래스가 있습니다. 각 속성은 뷰에 할당 할 뷰 모델의 인스턴스가됩니다. 코드가 디자인 모드에서 실행 중인지 또는를 사용하지 않는지 확인할 수 있습니다 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}}">

I don't understand why the other answers of this question wrap around the Designer.

The purpose of the View Model Locator is to allow your View to instantiate this (yes, View Model Locator = View First):

public void MyWindowViewModel(IService someService)
{
}

instead of just this:

public void MyWindowViewModel()
{
}

by declaring this:

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

Where ViewModelLocator is class, which references a IoC and that's how it solves the MainWindowModel property it exposes.

It has nothing to do with providing Mock view models to your view. If you want that, just do

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

The View Model Locator is a wrapper around some (any) Inversion of Control container, such as Unity for example.

Refer to:

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

반응형