티스토리 뷰

반응형

2022.11.30 - [WPF .NET] - Prism Library를 사용하는 개발자를 위한 안내 Part6 - TabControl Region Navigation

2022.11.25 - [WPF .NET] - Prism Library를 사용하는 개발자를 위한 안내 Part5 - Region & ContentControl Region Navigation

2022.11.18 - [WPF .NET] - Prism Library를 사용하는 개발자를 위한 안내 Part4 - Register Types

2022.11.15 - [WPF .NET] - Prism Library를 사용하는 개발자를 위한 안내 Part3 - DelegateCommand

2022.10.28 - [WPF .NET] - Prism Library를 사용하는 개발자를 위한 안내 Part2 - 프로젝트 구성 살펴 보기

2022.10.27 - [WPF .NET] - Prism Library를 사용하는 개발자를 위한 안내 Part1

2022.10.27 - [WPF .NET] - Prism Library를 사용하는 개발자를 위한 안내 Part1

 

Prism Libaray 7.0 부터 인터페이스를 이용한 컨테이너 사용 방법으로 변경되었습니다. 그래서, 어떤 IoC Container를 사용하더라도, 인터페이스를 구현하면 동일한 방법으로 사용할 수 있습니다.

현재, 기본으로 제공되는 컨테이너는 DryIoC와 Unity 두가지 종류 입니다. 

저는 요즘 프로젝트 생성할 때 DryIoC를 선택해서 사용하고 있습니다. 이전 버전에 MEF 방식은 버려진 것으로 보입니다. MEF도 나름 괜찮았는데....

ASP.NET Core에 익숙한 개발자는 종속성 등록시 Transients, Singletons 및 Scoped 유형 중 하나를 선택해서 등록했을 것입니다. 그러나, 데스크톱(WPF) 및 모바일 애플리케이션(UWP) 개발을 위한 라이브러리이기 때문에 Scoped를 사용하지 않으며, 구현도 하지 않았다고 합니다.

RegisterTypes에서 사용 가능한 containerRegistry.RegisterScoped는 Prism.Forms 내에서만 구현되어있다고 합니다.
https://github.com/PrismLibrary/Prism/discussions/2655#discussioncomment-2016936

1. 유형 등록(Register Types)

애플리케이션에서 사용할 유형을 등록하는 작업은 App.xaml.csRegisterTypes() 메서드에서 진행합니다.

지원하는 등록 방법은 아래와 같습니다.

  • Transient 등록
  • Singleton 등록
  • 생성된 인스턴스 등록
  • 기타 등록
    • 다이얼로그 윈도우 등록
    • 다이얼로그 화면 등록
    • RegionNavigation 화면 등록
    • 그외...

2. Transient 등록

  • 컨테이너에서 Resolve를 사용할 때 마다, 새로운 인스턴스를 만든 후 반환할 유형을 등록합니다. 
  • 유형을 등록하는 일반적인 이유는 인터페이스와 클래스를 연결 시켜주기 위해서 사용합니다.
  • 인터페이스가 존재하지 않는 View나 class들(Sample1.xaml, Person.cs)은 등록하지 않아도, Resolve가 가능하며 그 때마다 인스턴스가 만들어져서 반환 됩니다.
  • Register 메서드를 이용해서 등록합니다.
    • 예) containerRegister.Register<IPerson, Person>();

아래 예제를 보면 Person 클래스를 만들고, 유형 등록을 하지 않았지만, _containerProvider.Resolve<Person>()을 이용해서 인스턴스를 시킨 후 2개의 인스턴스를 비교하는 것 입니다.

_containerProvider는 생성자 주입을 통해 입력된 컨테이너입니다.

인스턴스를 비교할 때는 Equals를 사용합니다.

/// <summary>
/// Person
/// </summary>
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool Sex { get; set; }
    public string Address { get; set; }
}

...............................................................

/// <summary>
/// Person 생성
/// </summary>
private void OnCreatePerson()
{
    var person1 = _containerProvider.Resolve<Person>();
    var person2 = _containerProvider.Resolve<Person>();
    if(person1.Equals(person2))
    {
        MessageBox.Show("It's the same instance");
    }
    else
    {
        MessageBox.Show("They are different instances");
    }
}

결과

3 Singleton 등록

  • 컨테이너에서 Resolve를 사용할 때 마다, 동일한 인스턴스를 반환합니다. 
  • 유형을 등록하는 일반적인 이유는 전체 애플리케이션에서 1개의 인스턴스만 존재해야 하거나, 여러개의 인스턴스가 필요 없는 경우에 사용합니다.
  • RegisterSingleton 메서드를 이용해서 등록 합니다.

App.xaml.cs

아래와 같이 RegisterTypes에 등록을 한 후 실행해서 Create Person 버튼을 클릭합니다.

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    //처음 Person을 호출하면, Person 인스턴스를 하나 만들고, 다음 호출부터는 그 인스턴스를 반환
    //containerRegistry.RegisterSingleton<Person>();
    //처음 Person을 호출하면, 미리 정의된 Person 인스턴스를 만들고, 다음 호출부터는 그 인스턴스를 반환
    containerRegistry.RegisterSingleton<Person>(() => new Person { Id = 100, Name = "kaki104", Sex = true });
    //처음 Person을 호출하면, container를 이용해서 작업을 진행할 수 있습니다. 다만, 아래 코드는 오류가 발생합니다. 재귀호출이 되어버려서..
    //containerRegistry.RegisterSingleton<Person>(container => container.Resolve<Person>());
}

결과

4. 생성된 인스턴스 등록

  • Singleton 등록하기와 차이점
    • 미리 생성한 인스턴스를 컨테이너에 등록할 수 있습니다.
    • 식별자를 지정해서 하나의 인스턴스를 여러개 등록해서 사용하거나, 하나의 유형을 이용해서 다수의 인스턴스를 만들고, 각각 등록해서 사용할 수 있습니다.
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    ...
    
    var kaki105 = new Person { Id = 1, Name = "kaki105", Sex = false };
    containerRegistry.RegisterInstance(kaki105, "kaki105");
    containerRegistry.RegisterInstance(kaki105, "kaki106");
}

Xaml에 버튼하나 추가하고, 커맨드 추가해서 클릭시 아래 코드가 동작되게 만듭니다.

private void OnCreatePerson2()
{
    var kaki105 = _containerProvider.Resolve<Person>("kaki105");
    var kaki106 = _containerProvider.Resolve<Person>("kaki106");
    ShowMessage(kaki105, kaki106, "Create Person2");
}

private void ShowMessage(object one, object two, string title = "")
{
    if(one == null || two == null)
    {
        MessageBox.Show("Both objects must be not null", title);
        return;
    }
    if (one.Equals(two))
    {
        MessageBox.Show("It's the same instance", title);
    }
    else
    {
        MessageBox.Show("They are different instances", title);
    }
}

/// <summary>
/// Person 생성
/// </summary>
private void OnCreatePerson()
{
    var person1 = _containerProvider.Resolve<Person>();
    var person2 = _containerProvider.Resolve<Person>();
    ShowMessage(person1, person2, "Create Person");
}

결과

5. 기타 등록

기타 등록에 나오는 내용들은 추후 관련 포스팅을 할 때 추가하도록 하겠습니다.

 

* 다이얼로그 윈도우 등록

  • DialogService를 이용하는 경우 베이스로 사용되는 기본 Window 컨트롤을 커스텀되어 있는 Window 컨트롤로 변경하는 경우 사용합니다.
  • 반드시 System.Windows.Window 클래스를 상속 받은 윈도우여야 합니다.
containerRegistry.RegisterDialogWindow<SampleWindow>();

* 다이얼로그 화면 등록

  • DialogService를 이용해서 만든 화면을 등록하는데 사용합니다.
  • 반드시 IDialogAware를 상속 받은 View 혹은 ViewModel을 가지고 있어야 합니다.
public class CopyViewModel : IDialogAware
{
// IDialogAware 인터페이스가 구현 되어 있어야 합니다.
}

............

containerRegistry.RegisterDialog<CopyView, CopyViewModel>();

* RegionNavigation 화면 등록

RegionManager의 RequestNavigate를 이용해서 Navigate를 시켜야 하는 화면을 등록하는데 사용합니다.

containerRegistry.RegisterForNavigation<LoginView>();
containerRegistry.RegisterForNavigation<HomeView>();

6. 소스

WpfTest/PrismStep3 at master · kaki104/WpfTest (github.com)

 

GitHub - kaki104/WpfTest

Contribute to kaki104/WpfTest development by creating an account on GitHub.

github.com

 

반응형
댓글