4. 무비 파인더
Spring.NET IoC 특징에 대한 간단한 데모는 마틴 파울의 아티클에서 찾을수 있는데 다음의 주소 링크를 참고하시면 됩니다.(http://martinfowler.com/articles/injection.html

이글은 영화검색설비에 IoC의존성주입(DI)를 예제로 사용했습니다.  내용은 어떻게 하나의 MovieLister 객체가 IMoveFinder 인터페이스를 실행하기 위해 참조를 받는지를 설명합니다.

IMovieFinder는 모든 영화목록을 반환합니다. 그리고 MovieLister는 특정 감독 이름과 일치하는 Movie객체의 배열을 반환하기 위해 이 리스트를 필터링 합니다. 이 문서는 어떻게 Spring.NET IoC 컨테이너가 MovieLister 인스턴스에 적절한 IMovieFider를 구현하는지 보여줍니다.MovieFinder 응용 프로그램을 위한 C#코드는 examples/Spring/Spring.Example.MovieFinder 디렉토리에 있습니다.(예제 다운로드: http://www.springframework.net/download.html )



4.1 무비 파인더 시작하기무비 파인더 예제를 위한 시작 클래스는 단일 응용프로그램 시작점을 가지는 평범한 닷넷 클래스인 MovieApp class 입니다.


using System;

namespace Spring.Examples.MovieFinder

{

    public class MovieApp   

 {

        public static void Main()
       {

        }
    }
}

MovieLister 클래스의 인스턴스로부터 하나의 참조를 얻기 위해 우리는 무엇을 해야 할까요? Spring.NET 예제로 부터 우리는 Spring.NET의 IoC 컨테이너, IApplicationContext 로 부터 하나의 참조를 얻을 것 입니다. IApplicationContext 인스턴스로 부터 참조를 얻는 방법은 여러가지 입니다. 그러나 우리는 이 예제를 위해 표준 .NET 응용 프로그램 설정 파일내의 사용자 구성 영역에서 인스턴스화된 IApplicationContext를 사용할 것 입니다.

<?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <configSections>
             <sectionGroup name="spring">
                 <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
                 <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
            </sectionGroup>
       </configSections>
      <spring>
         <context>
             <resource uri="config://spring/objects"/>
         </context>
         <objects xmlns="http://www.springframework.net">
             <description>An example that demonstrates simple IoC features.</description>
         </objects>
      </spring>
</configuration>

예제 응용 프로그램에서 사용될 객체는 <object />엘리먼트 안에 <object /> 엘리먼트로써 설정되어질 것 입니다.


MovieApp 클래스의 메인메서드의 몸체에 이제 조금 살을 붙여 보겠습니다.

using System;
using Spring.Context;
namespace Spring.Examples.MovieFinder
{

    public class MovieApp
    {
        public static void Main()
        {
            IApplicationContext ctx = ContextRegistry.GetContext();
        }
    }
}

MovieApp 소스에 하나의 using요소를 추가했습니다. Spring.Context 네임스페이스는 IApplicationContext 클래스에 응용 프로그램이 접근할수 있게 해줍니다. 이것은 응용 프로그램이 IoC 컨테이너에 접근할수 있는 의미를 나타낸다. 그 코드라인

IApplicationContext ctx = ContextRegistry.GetContext();
은 응용 프로그램 구성 파일(application config file)에서 완벽하게 구성된 IApplicationContext 구현을 <object /> 섹션에서 되찾아 올 것이다.


4.2 첫 객체 정의아직은 객체가 응용 프로그램 구성 파일에 정의되어 있지 않습니다. 그래서 지금 그것을 하려고 합니다. 우리는 MovieLister 인스턴스를 위한 매우 최소한의 XML 정의를 다음의 코드 조각에서 볼수 있습니다.<objects xmlns="http://www.springframework.net">    <object name="MyMovieLister"                type="Spring.Examples.MovieFinder.MovieLister, Spring.Examples.MovieFinder">    </object></objects>


MovieLister 클래스의 전체 어셈블리 이름은 객체 정의의 type 어트리뷰트에 정의되었고, MyMovieLister라는 고유한 아이디가 할당되었습니다. 이 ID를 사용하여 정의된 객체의 인스턴스를 아래의 코드에서 처럼 찾을 수 있습니다.

...
public static void Main ()
{
    IApplicationContext ctx = ContextRegistry.GetContext();
    MovieLister lister = (MovieLister) ctx.GetObject ("MyMovieLister");
}
...

lister 인스턴스는 IMovieFinder 인터페이스의 적당한 구현을 아직 가지고 있지 않습니다.
MoviesDirectedBy 메서드의 사용을 시도하면 IMovieFinder의 참조를 lister 인스턴스가 아직 가지고 있지 않기 때문에 아마도 NullReferenceException의 결과를 얻을 것입니다.
IMovieFinder 구현에 대한 XML 구성은 아래처럼 lister 인스턴스를 주입해야 합니다.

<objects xmlns="http://www.springframework.net">
    <object name="MyMovieFinder"
               type="Spring.Examples.MovieFinder.SimpleMovieFinder, Spring.Examples.MovieFinder"/>
    </object>
</objects>


4.3 세터 주입우리가 원하는 무언가는 MyMovieLister id에 의해 식별된 MovieLister 안에  MyMovieFinder id에 의해 식별된 IMovieFinder 인스턴스를 주입하는 것인데 세터 인젝션으로 이것을 성취할 수 있다. 다음의 XML 코드를 보자.<objects xmlns="http://www.springframework.net">    <object name="MyMovieLister"                type="Spring.Examples.MovieFinder.MovieLister, Spring.Examples.MovieFinder">        <!-- using setter injection... -->        <property name="movieFinder" ref="MyMovieFinder"/>    </object>

    <object name="MyMovieFinder"
               type="Spring.Examples.MovieFinder.SimpleMovieFinder, Spring.Examples.MovieFinder"/>
    </object>
</objects>

MyMovieLister 객체가 응용 프로그램 내의 IApplicationContext로 부터 검색될 때 Spring.NET IoC 컨테이너는 MyMovieLister 객체의 MovieFinder 프로퍼티가 MyMovieFinder 객체를 참조 주입할 것입니다. 응용 프로그램에서 참조하는 MovieLister객체는 완벽하게 설정되고 응용 프로그램에서 사용할 준비가 됩니다.

...
public static void Main ()
{
    IApplicationContext ctx = ContextRegistry.GetContext();
    MovieLister lister = (MovieLister) ctx.GetObject ("MyMovieLister");
    Movie[] movies = lister.MoviesDirectedBy("Roberto Benigni");
    Console.WriteLine ("\nSearching for movie...\n");
    foreach (Movie movie in movies)
    {
        Console.WriteLine (
            string.Format ("Movie Title = '{0}', Director = '{1}'.",
            movie.Title, movie.Director)
        );
    }
Console.WriteLine ("\nMovieApp Done.\n\n");
}
...

MovieLister 클래스의 XML 구성을 안전하게 돕기 위해 MovieFinder 프로퍼티에 대한 값을 지정해야 합니다. 여러분은 MovieLister의 MovieFinder 프로퍼티에 [Required] 어트리뷰트를 지정할 수 있습니다. 예제코드는 이 어트리뷰트를 보여줍니다.


4.4. 생성자 주입응용 프로그램 구성 파일에 IMovieFinder인터페이스의 또 다른 실행을 정의해보도록 하겠습니다.

<object name="AnotherMovieFinder"

           type="Spring.Examples.MovieFinder.ColonDelimitedMovieFinder, Spring.Examples.MovieFinder">

</object>


이 XML 조각은 콜론으로 구분된 텍스트 파일을 사용하는 IMovieFinder 실행을 의미하고 있습니다. 이 클래스에 대한 C# 코드는 싱글 생성자를 정의하고 인수는 System.IO.FileInfo 입니다.응용 프로그램내에서 이 객체를 가져오기 위한 객체 정의는 아래의 코드와 같습니다.


IMovieFinder finder = (IMovieFinder) ctx.GetObject ("AnotherMovieFinder");


하지만 이 코드는 Spring.Objects.Factory.ObjectCreationException 이라는 치명적인 결과를 낼 것 입니다. 왜냐하면 Spring.Example.MovieFinder.ColonDelimitedMovieFinder 클래스가 인수가 포함된 기본 생성자를 가지고 있지 않기 때문입니다. 

만약에 여러분이 IMovieFinder 인터페이스를 사용하기를 원한다면 여러분은 생성자 인수를 XML 파일에 추가해야 합니다.

그 코드는 아래와 같습니다.


<object name="AnotherMovieFinder"

           type="Spring.Examples.MovieFinder.ColonDelimitedMovieFinder, Spring.Examples.MovieFinder">

           <constructor-arg index="0" value="movies.txt"/>

</object>


<constructor-arg/> 는 관리되는 객체 생성자에 생성자 인수를 추가하기 위해 사용됩니다. Spring.NET IoC 컨테이너는 Spring.Examples.MovieFinder.ColonDelimitedMovieFinder의 단일 생성자가 필요로 하는 System.IO.FileInfo의 인스턴스로 내의 movies.txt 문자열을 변환하기 위해 System.ComponentModel.TypeConverter가 제공하는 기능을 사용합니다.


그래서 예제 응용 프로그램의 구성 파일은 다른 객체 정의를 가지는 IMovieFinder 인터페이스를 2개 가지고 있습니다.만약에 MyMovieLister객체로 바꿔 사용하고 싶다면 아래 처럼 설정하면 됩니다.


<object name="MyMovieLister"

            type="Spring.Examples.MovieFinder.MovieLister, Spring.Examples.MovieFinder">

        <!-- lets use the colon delimited implementation instead -->

        <property name="movieFinder" ref="AnotherMovieFinder"/>

</object>

<object name="MyMovieFinder"

            type="Spring.Examples.MovieFinder.SimpleMovieFinder, Spring.Examples.MovieFinder"/>

</object>

<object name="AnotherMovieFinder"

           type="Spring.Examples.MovieFinder.ColonDelimitedMovieFinder, Spring.Examples.MovieFinder">

          <constructor-arg index="0" value="movies.txt"/>

</object>


이 코드가 보여주는 중요한 점은 구현된 응용 프로그램의 내용을 변경하기 위해 다시 컴파일 할 필요없이 간단하게 변경할수 있다는 것입니다.


이상 무비파인더 예제를 이용한 IoC와 주입에 대한 예제를 모두 살펴 보았습니다.





profile

소프트웨어라는 도구를 천문분야에 접목하는 것에 대해 관심을 가지고 있는 1인 입니다.

 

 

한국천문연구원(KASI) 한국형 외계지적생명체 탐색 기술자문 (2010)

Microsoft Visual C# MVP(2009-2010)

세티의 Lonely Star 블로그 운영


facebook: http://www.facebook.com/setipark