[Prism] 020. 고급 기능 및 활용 사례, 이벤트 버스 (EventAggregator) 활용

WPF(Windows Presentation Foundation)는 데스크탑 애플리케이션을 개발하기 위한 강력한 플랫폼입니다. Prism은 WPF 애플리케이션을 위한 모듈식 개발 프레임워크로서, 재사용 가능하고 유지 관리하기 쉬운 애플리케이션을 구성할 수 있도록 지원합니다. 이 글에서는 Prism의 고급 기능과 특히 이벤트 버스(EventAggregator)의 활용 사례에 대해 알아보겠습니다.

1. Prism 개요

Prism은 WPF 애플리케이션의 구조를 개선하고, 모듈화, 테스트 용이성, 유지 관리성을 높이는 데 도움을 주는 프레임워크입니다. MVVM(Model-View-ViewModel) 패턴을 지원하며, 이를 통해 개발자는 사용자 인터페이스(U.I.)와 비즈니스 로직을 명확하게 분리할 수 있습니다.

2. 고급 기능

2.1. 모듈화

Prism의 가장 큰 특징 중 하나는 모듈화입니다. 애플리케이션의 기능을 독립적인 모듈로 나누어 개발할 수 있습니다. 각 모듈은 자신의 View, ViewModel 및 비즈니스 로직을 가질 수 있으며, 필요할 때만 로드하여 성능을 극대화할 수 있습니다.

예제: 모듈 구성


public class MyModule : IModule
{
    public void Initialize()
    {
        // 뷰를 리졸빙하고 등록
        var myView = Container.Resolve();
        RegionManager.RegisterViewWithRegion("MainRegion", () => myView);
    }
}

2.2. 의존성 주입

Prism은 Unity, Autofac과 같은 여러 의존성 주입(D.I.) 컨테이너를 지원합니다. 이를 통해 애플리케이션 내의 컴포넌트를 쉽게 관리할 수 있습니다.

예제: Unity를 이용한 D.I.


public class Bootstrapper : UnityBootstrapper
{
    protected override void ConfigureContainer()
    {
        base.ConfigureContainer();
        Container.RegisterType();
    }
}

2.3. 지역화 및 리소스 관리

Prism은 리소스 관리 및 지역화를 위한 다양한 기능을 제공합니다. 이를 통해 다양한 언어와 지역의 사용자에게 맞춤형 인터페이스를 제공할 수 있습니다.

3. 이벤트 버스 (EventAggregator)

EventAggregator는 여러 뷰와 뷰 모델 간의 느슨한 결합을 가능하게 해주는 중요한 기능입니다. 이 컴포넌트는 다양한 모듈이나 구성 요소 간의 통신을 지원하며, Publish-Subscribe 패턴을 사용합니다.

3.1. EventAggregator 개념

EventAggregator를 사용하면 애플리케이션의 특정 이벤트에 대해 구독하고, 이벤트가 발생하면 이를 전달받아 처리할 수 있습니다. 이를 통해 구독자와 게시자의 결합을 최소화하여 재사용성과 테스트 용이성을 높입니다.

예제: EventAggregator 구현


public class MyEvent : PubSubEvent { }

public class Publisher
{
    private readonly IEventAggregator _eventAggregator;

    public Publisher(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
    }

    public void PublishMessage(string message)
    {
        _eventAggregator.GetEvent().Publish(message);
    }
}

public class Subscriber
{
    public Subscriber(IEventAggregator eventAggregator)
    {
        eventAggregator.GetEvent().Subscribe(OnMessageReceived);
    }

    private void OnMessageReceived(string message)
    {
        Console.WriteLine($"Received message: {message}");
    }
}

3.2. EventAggregator 활용 사례

EventAggregator는 다양한 실제 애플리케이션에서 사용할 수 있으며, 다음과 같은 사례에서 효과적입니다.

사례 1: 상태 변경 통지

여러 뷰가 동일한 데이터를 공유하는 경우, 데이터를 변경했을 때 다른 뷰에 이를 통지하는 데 EventAggregator를 사용할 수 있습니다. 예를 들어, 사용자 프로필을 업데이트한 후, 다른 뷰에서 이를 즉시 반영하도록 할 수 있습니다.

예제: 사용자 프로필 업데이트


public class UserProfileUpdateEvent : PubSubEvent { }

public class ProfileViewModel
{
    private readonly IEventAggregator _eventAggregator;

    public ProfileViewModel(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
    }

    public void UpdateProfile(UserProfile updatedProfile)
    {
        // 프로필을 업데이트 후 이벤트 발행
        _eventAggregator.GetEvent().Publish(updatedProfile);
    }
}

public class DashboardViewModel
{
    public DashboardViewModel(IEventAggregator eventAggregator)
    {
        eventAggregator.GetEvent().Subscribe(OnProfileUpdated);
    }

    private void OnProfileUpdated(UserProfile updatedProfile)
    {
        // 대시보드에서 사용자 프로필 업데이트 처리
        CurrentUserProfile = updatedProfile;
    }
}

사례 2: 다양한 구성 요소 간의 원활한 통신

그림 편집기 애플리케이션을 예로 들 수 있습니다. 여러 도형(사각형, 원 등) 컴포넌트가 있을 때, 각 도형의 크기나 색상을 변경하는 이벤트가 발생하면 이를 EventAggregator를 통해 서로 통지할 수 있습니다.

예제: 도형 크기 변경 통지


public class ShapeSizeChangedEvent : PubSubEvent { }

public class Circle
{
    private readonly IEventAggregator _eventAggregator;

    public Circle(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
        _eventAggregator.GetEvent().Subscribe(OnSizeChanged);
    }

    public void ChangeSize(int newSize)
    {
        // 크기 변경 후 이벤트 발행
        _eventAggregator.GetEvent().Publish(newSize);
    }

    private void OnSizeChanged(int newSize)
    {
        // 새로운 크기로 특정 로직 수행
    }
}

4. 결론

Prism의 고급 기능과 EventAggregator의 활용은 WPF 애플리케이션의 복잡도를 줄이고, 코드 재사용성을 높이며 모듈화된 아키텍처를 가능하게 합니다. 서로 다른 구성 요소 간의 통신을 원활하게 하는 EventAggregator는 특히 대규모 애플리케이션에서 더욱 유용합니다. 이러한 기능들을 통해 개발자는 더 나은 품질의 소프트웨어를 효율적으로 개발할 수 있습니다.