티스토리 뷰

Previous Platforms

Prism 4.0 MEF Container 1

kaki104 2012. 2. 13. 15:30
반응형

Silverlight, WPF 프로젝트를 개발 할 때 Prism을 사용해서 개발하게 된다. 그런데, 대부분은 Unity Container만 사용하고 MEF Container를 사용하는 프로젝트는 잘 없는 것 같다. 간단하게 MEF Container를 이용하는 방법을 적어 보고자 한다. (Windows Phone 7도 Prism을 이용 할 수 있는데 Unity Container만을 지원한다.)

참고 포스트
Prism for Silverlight/MEF in Easy Samples. Part 1 - Prism Modules
http://www.codeproject.com/Articles/155835/Prism-for-Silverlight-MEF-in-Easy-Samples-Part-1-P

1. Prism 4.0

Developer's Guide to Microsoft Prism
http://msdn.microsoft.com/en-us/library/gg406140.aspx

프리즘은 WPF, Silverlight 등의 프로그램 개발 할 때 쉽게 설계하고, 개발하고, 유연성을 가지도록 개발을 하는 패턴을 제공해주는 툴이라고 생각하면 되겠다. Enterprise Library가 프리즘을 기반으로 만들어진 것 중 하나이다.

2. MEF Container

MEF(Managed Extensibility Framework)는 대규모 어플리케이션의 유연성, 유지보수 및 테스트를 하기 쉽게하는 기능을 제공하는 것으로, Prism에 포함되어 Unity Container와 함께 하나의 큰 축을 이루고 있다.

3. MEF Container를 구성하는데 제일 중요한 사항

Shell.xaml이 있는 메인 프로젝트에는 References에 Prism관련 DLL들이 Copy Local : True  되어 있어야 하고, 그 외의 다른 프로젝트에서는 모두 Copy Local : False가 되어 있어야 한다. 이 부분만 확실하게 해주면 프로젝트를 구성하는데 어려움이 없을 것이다.

4. 메인 모듈(PrismMEF1)
찾아서 보아야 하는 부분을 순서대로 보도록 하겠다.

App.xaml.cs

  private void Application_Startup(object sender, StartupEventArgs e)
  {
      //부트 스트리퍼로 시작
      (new Bootstrapper()).Run();
  }


Bootstrapper.cs

using System.Windows;
using Microsoft.Practices.Prism.MefExtensions;
using Microsoft.Practices.Prism.Modularity;
using System.ComponentModel.Composition.Hosting;
using PrismMEF1.Infrastructure;

namespace PrismMEF1
{
    /// <summary>
    /// 부트스트리퍼
    /// </summary>
    public class Bootstrapper : MefBootstrapper
    {
        /// <summary>
        /// 쉘 초기화
        /// </summary>
        protected override void InitializeShell()
        {
            base.InitializeShell();
            Application.Current.RootVisual = (UIElement)Shell;
        }


        protected override DependencyObject CreateShell()
        {
            //익스포트된 Shell.xaml를 임포트 시켜서 리턴
            return Container.GetExportedValue<Shell>();
        }

        /// <summary>
        /// 모든 MEF 콤포저블 카탈로그들이 들어가 있는 넘
        /// </summary>
        protected override void ConfigureAggregateCatalog()
        {
            base.ConfigureAggregateCatalog();

            //거기다가 이 프로젝트까지 카탈로그에 넣는데...왜 넣는걸까?
            AggregateCatalog.Catalogs.Add(new AssemblyCatalog(this.GetType().Assembly));
        }

        /// <summary>
        /// 모듈카탈로그를 만드는데 사용
        /// </summary>
        /// <returns></returns>
        protected override IModuleCatalog CreateModuleCatalog()
        {
            //모듈카탈로그 생성
            ModuleCatalog moduleCatalog = new ModuleCatalog();

            //ModuleName, Moduletype은 클래스 이름
            //즉시 다운로드
            moduleCatalog.AddModule
            (
                new ModuleInfo
                {
                    InitializationMode = InitializationMode.WhenAvailable,
                    Ref = "PrismMEF1.MainMenuModule.xap",
                    ModuleName = ModuleNames.MainMenuModuleImp,
                    ModuleType = "PrismMEF1.MainMenuModule.MainMenuModuleImp, PrismMEF1.MainMenuModule, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
                }
            );
            //다중에 다운로드
            moduleCatalog.AddModule
            (
                new ModuleInfo
                {
                    InitializationMode = InitializationMode.OnDemand,
                    Ref = "PrismMEF1.MDModule.xap",
                    ModuleName = ModuleNames.MDModuleImp,
                    ModuleType = "PrismMEF1.MDModule.MDModuleImp, PrismMEF1.MDModule, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
                }
            );

            //추가한 모듈카탈로그를 반환해야징;;
            return moduleCatalog;
        }
    }
}

Shell.xaml
<!--쉘에서 레전을 지정-->
    <ContentControl Grid.Row="1" Grid.Column="0"
                        prism:RegionManager.RegionName="mainMenuRegion" Grid.RowSpan="2" Margin="10,10,0,0"/>
    <ContentControl Grid.Row="1" Grid.Column="1"
                      prism:RegionManager.RegionName="subMenuRegion" Margin="10,10,10,0"/>
    <ContentControl Grid.Row="2" Grid.Column="1"
          prism:RegionManager.RegionName="contentRegion" Margin="10,10,10,0"/>


5. 메뉴 모듈(PrismMEF1.MainMenuModule)

MainMenuModuleImp.cs

using System.ComponentModel.Composition;
using Microsoft.Practices.Prism.MefExtensions.Modularity;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions;
using PrismMEF1.Infrastructure;
using PrismMEF1.MainMenuModule.Views;

namespace PrismMEF1.MainMenuModule
{
    [ModuleExport(typeof(MainMenuModuleImp))]
    public class MainMenuModuleImp : IModule
    {
        /// <summary>
        /// 레전 메니저 임포트
        /// </summary>
        [Import]
        public IRegionManager regionManager { private get; set; }

        /// <summary>
        /// 모듈이 로딩이 되자마자 지정된 레전에 들어간다.
        /// </summary>
        public void Initialize()
        {
            regionManager.RegisterViewWithRegion(RegionNames.MainMenuRegion, typeof(MainMenuView));
            regionManager.RegisterViewWithRegion(RegionNames.SubMenuRegion, typeof(SubMenuView));
        }
    }
}

6. 컨텐츠 모듈(PrismMEF1.MDModule)

using System.ComponentModel.Composition;
using Microsoft.Practices.Prism.MefExtensions.Modularity;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions;
using PrismMEF1.Infrastructure;
using PrismMEF1.MDModule.Views;

namespace PrismMEF1.MDModule
{
    [ModuleExport(typeof(MDModuleImp))]
    public class MDModuleImp : IModule
    {
        /// <summary>
        /// 레전 매니저 임포트
        /// </summary>
        [Import]
        public IRegionManager regionManager { private get; set; }

        public void Initialize()
        {
            //리전메니저를 임포트해서 불러들인 후에 리전중에 컨텐츠리진에 MDMainView를 붙인다.
            regionManager.RegisterViewWithRegion(RegionNames.ContentRegion, typeof(MDMainView));
        }

    }
}

7. 화면

접속 가능 주소 : http://kaki105.cafe24.com/PrismMef1/

1) 시작하면 메인메뉴모듈을 로딩해서 바로 표시

2) 컨텐츠모듈 다운로드 버튼을 누르면 컨텐츠 모듈을 다운로드 해서 표시해준다.

8. 이 포스트는 예전에 만들어 놓은 셈플 프로젝트를 빠르게 정리하기 위한 것이다.

PrismMEF1.zip
다운로드

반응형
댓글