통합검색
· 마을서비스란?  · 포럼마을  · 일반마을  · 테마마을  · 마을랭킹  · 활동왕
· 덱스퍼트란?  · TECBOX   · PRSBOX   · 이용안내  
· DEXT제품군  · 솔루션베이  · S/W & ESD 컴포넌트
· 프로그램베이
· LiveSeminar  · LiveConference
WPF & Silverlight 포럼마을입니다.
  마을등급 WPF & Silverlight   이 마을은 포럼마을 입니다이 마을은 자유가입제 마을 입니다 마을소개 페이지로 이동 전입신청
마을촌장촌장 서학수 주민 728 since 2008-07-17
우리마을 공지사항
질문&답변
강좌&팁
자유게시판
자료실
앨범
[마을 게시판]
WPF 강좌
랑데브 게시판
칼럼 게시판
개발자 고충상담
Dev Talk
자유토론방
벼룩시장
재나미 우스개
구인/프로젝트 정보
사람인 채용 게시판
  고객지원 게시판
마이 데브피아
 나의 e-Money 내역
 활동왕 My Page
 스크랩한 게시글보기
 쪽지관리
 주소록관리

 강좌&팁
 SL5...Twitter Client 10 (MEF 2)  | Silverlight 2011-06-05 오후 3:57:02
 kaki104  kaki104님께 메시지 보내기kaki104님을 내 주소록에 추가합니다.kaki104님의 개인게시판 가기 번호: 153 추천:0  / 읽음:6,768

Silverlight5...Twitter Client 10 (MEF 2 : MEF 확장)

 

지난번 MEF글에서 보면 프로젝트에서 뷰모델을 Export 시킨 후 각각의 Page에서 Import을 시켜서 사용하는 모습을 보여줬다.

그 정도만 사용하더라도 개발하는데 있어서 만은 도움이 된다.

 

그러나 그 정도는 MEF라는 빙산의 일각이라고 하겠다.

이번에는 MEF의 확장에 대해 이야기를 해 보겠다.

 

시작하기전에 여기를 클릭해서 내용을 한번 살펴 보기 바란다.

그림으로 MEF에 대한 개념에 대해서 설명을 해 놓아서 보기가 좋다.

 

 

이번에 작성할 내용은 다른 프로그램에서 Export한 내용을 내 프로그램에서 Import를 해서 사용하는 방법에 대해 설명을 하겠다. 이해를 돕기 위해 좀 각설을 하자면...

 

A라는 개발자가 실버라이트 프로젝트로 개발한 화면, 클래스, 등등을

내가 프로그램을 만들면서 A란 개발자가 공개해 놓은 XAP파일과 Interface DLL만 이용해서 그대로 사용한다는 개념이다.

 

물론 이렇게 사용하기 위해서는 A라는 개발자는 자신이 Export하려는 것을 인터페이스로 구성해야지만 하지만..

그렇게만 해 놓는다면, 누구나 자신이 일일이 그 기능들을 다 개발할 필요 없이 그냥 Import 시켜서 내가 만든것 처럼 사용

할 수 있을것이다. 현재 MS의 Prism4.0 프레임웩에 어느정도 표준화가 되어있는 상태이다.

몇년 후면 다른 사람이 만들어 놓은 기능만 Import , Import....시켜서 프로그램을 뚝딱 완성할 수 있는 시대가 올것이다.

 

 

일단 화면을 보자

 

트위터 클라이언트의 DevpiaMain 이란 이름의 새로운 어플리 케이션이다.

 

사진을 클릭하면

 

이런 팝업이 하나 뜨고

 

 

처음 화면의 오른쪽에 방금 선택한 사용자의 트윗 목록이 출력된다.

 

아래는 프로젝트에 포함되어 있는 내용들을 나타낸다.

 

 

이 정도 까지 했으면 이제는 뭔가 느끼는 것이 있을 것이다.

 

 

어제 Devpia 프로젝트를 인터페이스를 이용한 프로젝트로 변경을 한 후 그 인터페이스를 이용한 Export를 사용해서 뷰모델을 익스포트 시키고, 그 뷰모델을 DevpiaMain이라는 프로젝트에서 웹리퍼런스로 Import를 시켰다. 그래서 뷰모델과 뷰모델 내부에서 사용했던 상세 팝업창 출력하는 부분도 그대로 사용했다.

 

 

이 부분은 MEF에 대해 다시 한번 생각하는 시간이 필요할 것이다.

 

1. 전체 적인 흐름

 

1-1. DevpiaClassLibrary라는 클래스 라이브러리에 InheritedExport라는 Export를 상속 받는 인터페이스 IViewModel을 구현한다.

 

1-2. 그리고 Devpia 프로젝트에있는 CTwitterViewModel을 IViewModel에서 상속 받는다.

 

1-3. 실제 구현은 모두 CTwitterViewModel에 되어 있는 것이다.

 

1-4. DevpiaMain이란 프로젝트에서 DevpiaClassLibrary.Dll을 참조에 넣고

 

1-5. MainPage.xaml.cs에서 IViewModel을 ImportMany를 이용해서 Import한다.

 

1-6. 이때 IViewModel을 상속받아 구현되어있던 CTwitterViewModel이 Import가 되고 그 내용을 사용한다.

 

...

 

내가 생각하는 대략 적인 흐름이 이렇다. 다른 의견이 있다면 이야기를 해주기 바란다.

 

MEF에 대한 더 자세한 공부를 하려면 여기를 클릭해서 자세히 살펴 보는 것도 좋다.

 

 

2. Devpia프로젝트 수정

 

2-1. Add Project를 이용해서 ClassLibrary 프로젝트를 추가한다.

 

2-2. Cinterface.cs를 추가하고 내용을 구현 한다.

 

2-3. Converters 폴더를 추가하고 Devpia프로젝트에 있던 Converter들을 모두 이동 시킨다.

 

2-4. Model 폴더를 추가하고 Devpia프로젝트에 있던 Model들을 모두 이동 시킨다.

 

2-5. Static 폴더를 추가하고 Static Function을 이동 시킨다.

 

2-6. Devpia프로젝트에 Add Referance를 해서 DevpiaClassLibrary를 추가한다.

 

2-7. Devpia 프로젝트를 빌드해서 오류 사항 나오는 것을 모두 수정한다.

 

2-8. 모든 수정이 끝난 후 실행해서 원래 대로 결과가 출력되는지 확인한다.

 

2-9. 모든 기능이 정상적으로 작동하면 웹으로 배포한다.(난 내 홈페이지에 FTP로 올리기만 했다)

 

 

2-10. 중요 수정 부분

 

CInterface.cs

 

using System;
using System.Windows.Input;
using System.ComponentModel.Composition;
using DevpiaClassLibrary.Model;

namespace DevpiaClassLibrary
{
    [InheritedExport(typeof(IViewModel))]

   //ViewModel에서 사용되는 주요 기능에 대한 인터페이스 선언
    public interface IViewModel
    {
        CTwitterStatus TwitterStatus { get; set; }

 

        CTwitterSet TwitterSet { get; set; }

 

        CTwitterSet UserTwitterSet { get; set; }

 

        bool IsBusy { get; }

 

        void LoadTwitter();

 

        ICommand LoadCommand { get; }

 

        void LoadUserTwitter();

 

        ICommand LoadUserCommand { get; }

 

        void DetailView();

 

        ICommand DetailViewCommand { get; }

 

        void DetailViewOperation(Object lst);
    }
}

Devpia 프로젝 CTwitterViewModel.cs

 

...

using DevpiaClassLibrary;
using DevpiaClassLibrary.Model;        

    //IViewModel을 이미 상속 받았기 때문에 기존에 Export는 사용하지 않는다.

    //[Export(typeof(CTwitterViewModel))]
    public class CTwitterViewModel : IViewModel, INotifyPropertyChanged
    {

     ...

    }

 

    나머지 기존 소스는 그대로 사용

 

 

Devpia 프로젝 ListBoxView.xaml.cs

 

using DevpiaClassLibrary;
using DevpiaClassLibrary.Model;

public partial class ListBoxView : Page
    {
        //임포트 - 반드시 프로퍼티로 임포트를 시켜준다.

        //기존 임포트 타입에서 IViewModel로 임포트를 바꿔 준다.
        [Import(typeof(IViewModel), AllowRecomposition=true)]
        public IViewModel TwitterViewModel { get; set; }

 

    나모지 기존 소스도 그대로 사용

 

 

Devpia 프로젝 App.xaml

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:conv="clr-namespace:DevpiaClassLibrary.Converters;assembly=DevpiaClassLibrary"
             xmlns:DataStore="clr-namespace:Expression.Blend.DataStore.DataStore" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
             x:Class="Devpia.App">
    <Application.Resources>
        <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
       <ResourceDictionary Source="Assets/TwitterResourceDictionary.xaml"/>
      </ResourceDictionary.MergedDictionaries>

         <DataStore:DataStore x:Key="DataStore" d:IsDataSource="True"/>

            <!--컨버터-->
            <conv:TimeConverter x:Key="TimeConverter"/>
            <conv:LinkConverter x:Key="LinkConverter"/>
            <conv:ImageNameConverter x:Key="ImageNameConverter"/>
            <conv:ColorConverter x:Key="ColorConverter"/>
        </ResourceDictionary>
       
    </Application.Resources>
</Application>

    컨버터들의 위치가 변경되었기 때문에 진한글씨 부분 다시 써줌

 

2-11. 클래스 라이브러리와 인터페이스로 변경된 프로젝 실행 데모 실행 : 여기

 

 

3. DevpiaMain 프로젝 신규 작성

 

3-1. New Project로 Silverlight Application 추가 -> Silverlight5 선택 -> Web도 같이 선택

 

3-2. DevpiaClassLibrary.Dll 레퍼런스에 추가, 그외 MEF관련 리퍼런스 2개더 추가

 

3-3. 프로젝트 프로퍼티에서 OOB 프로젝트로 변경

 

3-4. ResourceDictionary 추가, TwitterItem이란 이름의 DataTemplate을 작성(상세 팝업에서 사용됨)

       자신의 취향에 맞게 이것 저것 변경하면 됨, 사진 클릭시 상세가 보이게 할려면 InvokeCommandAction

       부분만 복사해 붙여 넣기 하면됨

 

3-5. App.xaml에 리소스 추가, 역시 상세 팝업에서 사용되기 때문에 선언해줌

 

3-6. MainPage.xaml에 리스트 박스나 본인이 원하는 디자인..

        ****그런데 여기서 디자이너가 에러를 토해내는데..무시해야한다. 처리할 방법이 없다. MS에 건의를 하던가 해야지

        ****에러 내용은 리스트 박스에 이것 저것 바인딩 해놨는데 그걸 인스턴스 시켜서 보여줄려고 하니 문제가..쿨럭

 

3-7. MainPage.xaml.cs 수정(여기가 가장 중요한 부분!)

 

using System;
using System.Linq;
using System.Windows.Controls;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

using System.Collections.ObjectModel;
using DevpiaClassLibrary;

 

namespace DevpiaMain
{
    public partial class MainPage : UserControl
    {

        //여기서 ImportMany를 사용했는데. 그냥 Import를 사용해도 가능할듯

        //AllowRecomposition은 Import한 내용을 다시 재구성할 수 있는지 여부를 지정한다.

        //IViewModel 인터페이스를 사용하는 내용들을 가지고 오도록 한다.
        [ImportMany(typeof(IViewModel), AllowRecomposition=true)]
        public ObservableCollection<IViewModel> TwitterViewModels { get; set; }

 

        //MEF에서 지원하는 몇개의 Catalog중 하나를 이용한다. -> 자세한 내용은 상단의 링크들 참고

        public DeploymentCatalog catalog;

 

        public MainPage()
        {
            InitializeComponent();

 

            //카테고리를 웹리퍼런스로 인스턴스 시킨다.

            catalog = new DeploymentCatalog(new Uri("http://www.kakisoft.com/silverlight/10/ClientBin/Debug/Devpia.xap"));
            //catalog = new DeploymentCatalog("Devpia.xap");

 

            //xap파일 다운로드가 완료되면 그 다음 처리를 하도록 이벤트 등록
            catalog.DownloadCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(catalog_DownloadCompleted);

 

         //다운로드 시작
            catalog.DownloadAsync();
        }

 

        //다운로드 완료 후 처리

        void catalog_DownloadCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {

            //카탈로그를 초기화 시킨다.
            CompositionHost.Initialize(new DeploymentCatalog(), catalog);

 

                //Import를 초기화 한다.

            CompositionInitializer.SatisfyImports(this);

 

                //IViewModel로 하나를 입력

            IViewModel twitter = TwitterViewModels.First();

 

                //데이터 컨텍스트에 입력

            LayoutRoot.DataContext = twitter;

 

                //처음 조회 실행

            twitter.LoadTwitter();

        }

 

        private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
        }
    }
}

 

3-8. 빌드해서 오류를 수정한다.

 

3-9. 빌드가 완료대면 실행해서 결과를 확인한다.

 

3-10. 모든것이 정상적이면 배포한다.

 

3-11. DevpiaMain 데모 실행 : 여기

         이 프로그램도 오른쪽 마우스 버튼 눌러서 설치를 해야지만 정상적인 결과가 나온다.

 

 

 

4. MEF를 사용하지 안으면 실버라이트 4.0이 아니라는 사부의 이야기를 들으면서, 나름대로 만이 사용했다고 생각했었는데 전혀 새로운 형태로 사용을 해보고, 가능하다는 것을 알고나니 신기하고, 앞으로 응용분야가 만을 것이라는 생각이 들었다.

앞으로 프리즘을 배우고, EF4.1에서 사용되는 WCF RIA서비스까지 나오면 정말 행복한 날이 올 것이라고 상상해본다.

 

 

5. 이번회차 소스 다운 : Devpia10.zip, DevpiaMain.zip

 

 

[코멘트] 좋음
2011-06-17 01:11
 rainman  rainman님께 메시지 보내기rainman님을 내 주소록에 추가합니다.rainman님의 개인게시판 가기 
>> MEF를 사용하지 안으면 실버라이트 4.0이 아니라는
동의하기 어렵습니다..MEF를 실전에 사용해 보면 생각지도 못한 여러 가지 문제점에 봉착합니다.
MEF의 장점은 .Net 4.0에 포함된다는 것이 장점이나,그 외는 Repoitory Pattern의 하나로서
사실상 Unity Container와 별반 차이가 없습니다.
처음 접할 때, Learning Curve가 만만찮으며, 특히 error 발생 시 악명높은 뭉뚱그려 놓은 에러문장으로
디버깅에 애를 먹습니다.
prism같이 Composition UI를 한다면, 처음 접하는 분들은 Unity 등으로 접근하는 것이 훨씬 시간을 단축할 것이며
MEF는 충분히 연습하고 이해를 한 후에 ViewFactory 개념 등을 잘 설정하여 적용을 하는 것이 나으리라 생각합니다.
PRISM + MEF + MVVM으로 100 여개 View,15~6개의 U.I Module을 Dynamic Loading으로 만들어 본 결과,
분명 Unity보다 간결하고 편리한 점은 있지만 단지 Repository Pattern을 위한다면 Learning Curve 대비,
Unity가 훨씬 편하다는 것이 중론이고 저도 거기에 동의합니다.
저장 취소
[코멘트] 좋음
2011-06-17 21:15
 kaki104  kaki104님께 메시지 보내기kaki104님을 내 주소록에 추가합니다.kaki104님의 개인게시판 가기 
리플 감사합니다.
제가 이야기했던 부분은 최소한으로 MEF라도 사용해야지..기존 타이틀리 커플드한 개발 방법을 사용하지 말자~라는 의미였습니다.
적어 주신 내용은 저도 공감합니다.
저장 취소
코멘트쓰기
  좋음   놀람   궁금   화남   슬픔   최고   침묵   시무룩   부끄럼   난감
* 코멘트는 500자 이내(띄어쓰기 포함)로 적어주세요.
목록 보기   지금 보고 계시는 글을 회원님의 my Mblog >> 스크랩에 넣어두고 다음에 바로 보실 수 있습니다.  
회사소개  |   개인정보취급방침  |  제휴문의  |   광고문의  |   E-Mail 무단수집거부  |   고객지원  |   이용안내  |   세금계산서
사업자등록번호 안내: 220-81-90008 / 통신판매업신고번호 제 2017-서울구로-0055호 / 대표: 홍영준, 서민호
08390, 서울시 구로구 디지털로32길 30, 1211호 / TEL. 02_6719_6200 / FAX. 02-6499-1910
Copyright ⓒ (주) 데브피아. All rights reserved.