실버라이트(SilverLight) 강좌와TIP 게시판입니다. - 시삽보기

제목: 환상의 궁합! MVVM+Command Pattern+Dependency Injection #2
글쓴이: gongdo
평점: 없음
조회: 1918

원문은 : http://gongdosoft.com/365


MVVM+Command Pattern+Dependency Injection #1에 이어지는 Ninject를 사용한 Dependency Injection편이에요 :D

Ninject는 ‘번개처럼 빠른 인젝션’을 모토로 한 DI 프레임워크죠. Unity랑 비교해 보면 Unity가 전통적인 개발자에게 친숙한 인터페이스와 네이밍을 가진 반면 Ninject는 모던하고 약간은 팬시한 문법과 네이밍을 가졌고 다양한 조건에서 좀 더 자동화된 인젝션을 지원한다는 느낌이 들어요. 여튼 이 전에 만든 프로젝트를 정말로 약간만 수정하면 Unity를 Ninject로 바꿀 수 있어요. 이것이 바로 모듈화된 프로그래밍의 장점이죠 ;~)

우선 프로젝트 먼저 받아가시고요~


1. Ninject 라이브러리 참조

당연하겠지만 제일 먼저 라이브러리를 교체해야겠죠?

image 

Ninject는 현재 5개의 어셈블리로 이루어져 있고 3개는 Extension, 2개는 거의 필수로 사용되는 어셈블리죠. 그 중 필수인 Ninject.Core와 Ninject.Conditions를 참조하면 돼요. 
※Ninject.Condition 역시 사실 필수는 아니지만 프로젝트가 조금만 커져도 거의 필수로 사용됩니다.

2. ServiceConfiguration 수정

  1. /// <summary>  
  2. /// 서비스에서 사용할 인젝션 매핑을 설정하는 클래스  
  3. /// </summary>  
  4. public class ServiceConfiguration : StandardModule  
  5. {  
  6.     public override void Load()  
  7.     {  
  8.         bool isBlend = App.IsBlend;  
  9.         bool isWeb = !isBlend;  
  10.   
  11.         // IPhotoSerivce에 대한 바인딩 설정  
  12.         // 블렌드에서 실행할 때 바인딩만 다르게 표현  
  13.         if (isBlend)  
  14.         {  
  15.             Bind< IPhotoService>().To< MockPhotoService>();  
  16.         }  
  17.         else  
  18.         {  
  19.             Bind< IPhotoService>().To< LivePhotoService>().Only(When.Context.Variable("ServiceName").IsNotDefined);  
  20.             Bind< IPhotoService>().To< LivePhotoService>().Only(When.Context.Variable("ServiceName").EqualTo("Live"));  
  21.             Bind< IPhotoService>().To< FlickrPhotoService>().Only(When.Context.Variable("ServiceName").EqualTo("Flickr"));  
  22.             Bind< IPhotoService>().To< DaumPhotoService>().Only(When.Context.Variable("ServiceName").EqualTo("Daum"));  
  23.             Bind< IPhotoService>().To< NaverPhotoService>().Only(When.Context.Variable("ServiceName").EqualTo("Naver"));  
  24.         }  
  25.   
  26.         // 공통으로 사용할 바인딩  
  27.         // 서비스 제공자의 목록을 싱글턴으로 바인딩  
  28.         Bind< PhotoServiceProviderList>().ToConstant< PhotoServiceProviderList>(  
  29.             new PhotoServiceProviderList  
  30.             {  
  31.                 new PhotoServiceProvider { Name = "Live", DisplayName = "Live", LogoSource = "/MashupImageSearch;component/Resource/WindowsLive2_20.png" },  
  32.                 new PhotoServiceProvider { Name = "Flickr", DisplayName = "Flickr", LogoSource = "/MashupImageSearch;component/Resource/flickr2_20.png" },  
  33.                 new PhotoServiceProvider { Name = "Daum", DisplayName = "Daum", LogoSource = "/MashupImageSearch;component/Resource/daum_20.png" },  
  34.                 new PhotoServiceProvider { Name = "Naver", DisplayName = "Naver", LogoSource = "/MashupImageSearch;component/Resource/naver_20.png" },  
  35.             }  
  36.         ).Using< SingletonBehavior>();  
  37.     }  
  38. }  

Unity가 UnityContainer를 제공했던 것과 유사하게 Ninject는 StandardModule을 제공해요. Ninject에서 Module이란 하나의 서비스를 구성하는 DI들의 바인딩 구성을 정의하죠.

바인딩(매핑)을 등록하는 문장도 굉장히 다른데요, RegisterType()이라는 하나의 메서드로 인자의 위치나 배열에 따라 순서를 정했던 Unity와 달리 Ninject는 Bind<타입>().To<타입>().조건… 과 같은 명시적인 형식을 가지고 있어요. 마치 LINQ 표현식의 발전 과정을 보는 듯하죠.

동적 조건 식은 조금 복잡한데요, Unity가 단순히 이름만 가지고 바인딩을 결정했던 것과는 달리 Ninject는 굉장히 다양한 시나리오와 커스터마이징이 가능한 파라미터들로 바인딩을 결정할 수 있어요. Only(When.Context.Variable(“키”).조건…과 같이 “오직 컨텍스트에 특정 변수가 조건을 만족할 때만 바인딩”으로 글을 읽듯이 읽을 수 있죠. 굉장히 가독성이 좋은 문법이라고 봐요. 다만 지네릭과 람다 익스프레션 문법을 굉장히 많이 활용하기 때문에 익숙하지 않다면 어려울 수 있겠네요.

마지막으로 Unity의 RegisterInstance()메서드는 Ninject는 Bind<타입>().ToConstant<타입>() 으로 표현하는 걸 볼 수 있고 인젝션할 대상의 라이프 타임 관리를 .Using<라이프타임 동작>() 과 같이 할 수있어요. 여기에서 서비스 제공자의 목록은 항상 같으므로 단순한 SingletonBehavior로 지정했죠.

3. ServiceLocator 수정

  1. /// <summary>  
  2. /// 서비스에서 사용할 설정 모듈에서 타입을 제공하는 클래스  
  3. /// </summary>  
  4. public class ServiceLocator  
  5. {  
  6.     #region Singlton 컨테이너  
  7.     private static IKernel _kernel;  
  8.     /// <summary>  
  9.     /// 클래스 초기화.  
  10.     /// 서비스에서 사용할 DI 컨테이너를 초기화합니다.  
  11.     /// </summary>  
  12.     static ServiceLocator()  
  13.     {  
  14.         if (_kernel == null)  
  15.         {  
  16.             _kernel = new StandardKernel(new ServiceConfiguration());  
  17.         }  
  18.     }  
  19.   
  20.     /// <summary>  
  21.     /// 주어진 타입에 대한 인젝션을 수행한 참조를 반환합니다.  
  22.     /// </summary>  
  23.     /// <typeparam name="T">인젝션을 처리할 대상</typeparam>  
  24.     /// <returns>인젝션이 처리된 결과</returns>  
  25.     public static T Get< T>()  
  26.     {  
  27.         return _kernel.Get< T>();  
  28.     }  
  29.   
  30.     /// <summary>  
  31.     /// 주어진 타입에 대한 인젝션을 수행한 참조를 반환합니다.  
  32.     /// </summary>  
  33.     /// <typeparam name="T">인젝션을 처리할 대상</typeparam>  
  34.     /// 파라미터 이름  
  35.     /// <returns>인젝션이 처리된 결과</returns>  
  36.     public static T Get< T>(string name)  
  37.     {  
  38.         return _kernel.Get< T>(With.Parameters.Variable("ServiceName", name));  
  39.     }  
  40.     #endregion Singlton 컨테이너  
  41.   
  42.     /// <summary>  
  43.     /// 설정에 따라 이미지 검색 뷰모델의 인스턴스를 반환합니다.  
  44.     /// </summary>  
  45.     public ImageSearchViewModel ImageSearchViewModel  
  46.     {  
  47.         get { return Get< ImageSearchViewModel>(); }  
  48.     }  
  49.   
  50.     /// <summary>  
  51.     /// 설정에 따라 포토 서비스 제공자의 목록을 반환합니다.  
  52.     /// </summary>  
  53.     public PhotoServiceProviderList PhotoServiceProviders  
  54.     {  
  55.         get { return Get< PhotoServiceProviderList>(); }  
  56.     }  
  57. }         

Unity에서는 UnityContainer가 인젝션 바인딩(매핑) 정보를 보관하고 관리하는 역할을 모두 수행하지만 Ninject는 Kernel이 관리하는 Module에서 인젝션 바인딩 정보를 이용하여 인젝션을 관리해요. 특별히 다른 점은 없고 다만 파라미터를 줄 때도 Kernel.Get<타입>(With.Parameters.Variable(“변수이름”, 변수값) 같은 식으로 명시적이고 가독성 있는 문법을 지원해요.

이 정도 수정만으로 Unity를 Ninject로 대체하는 마이그레이션이 끝났어요. 실행 결과는 당연히 동일하고요. 간단하죠?

DI 자체에 대해서는 언제 한번 자세히 다루고 싶지만 아직 내공이 딸려서 정확한 설명은 힘드네요. 시간도 부족하고요. 우선은 지금까지 했던 프로젝트를 기반으로 지식을 확장해가면서 경험을 쌓아도 충분할거라고 봐요.

작성자 정보

글등록 +12 3154
덧글등록 +3 419
이름: gongdo(gongdo )

Level 56
 [EXP.221/250 ]


메일: gongdosoft골뱅이live.com

홈페이지: gongdosoft.com
자기소개
유령회사라고 말 했잖아!
글 공유하기 |
 tweet facebook
2009-01-31 오후 5:36:03
IP: 125.131.230.25
        
트랙백 주소 : http://www.hoons.kr/19561/BoardTrackback.aspx ()
등록된 트랙백 0

나도한마디
태그로 엮인글 리스트
  [실버라이트 Q&A] Silverlight Developer 런타임 설치라하는 메세지가 나옵니다... 평가안됨 흩날이
  [실버라이트 Q&A] 페이지에 이미지 바인딩 하는 법이 궁금합니다. 평가안됨 풍술사
  [실버라이트 Q&A] 실버라이트 4 웹캠 사용 질문 평가안됨 리미
  [ASP.NET Q&A] 실버라이트 asp.net 연결 질문입니다. 평가안됨 푸른곰팡이
  [실버라이트 Q&A] 실버라이트 asp.net 연결 질문입니다. [1]+1 평가안됨 푸른곰팡이
  [실버라이트 팁] [Tip] Silverlight + EF4.0 평가안됨 juooni
  [실버라이트 Q&A] WCF 서비스로 DB연결시.... [2] 평가안됨 조재문
  [구인&교육정보] [정규직구인] 초급 실버라이트 개발자를 찾습니다. 평가안됨 박PD
  [실버라이트 Q&A] html의 값을 Xaml로 불러들이는데 에러가 생겼습니다. 평가안됨 YooN
  [자유게시판] 왕초짜의 푸념...... [8] 파일첨부 평가안됨 YooN


사용자 정보

close