Spring.Net을 이용한 DI(Dependency Injection) 활용 - Part 3

안녕하세요. 꽃미남 입니다.

Spring.Net을 이용한 DI 활용 세번째 글입니다.
몇가지 설정에 대하여 적어보도록 하겠습니다.

예제 소스 : springnet_di3.zip (13.78 kb)

설정 파일 분리

App.Config에 넣었던 설정 정보를 XML 파일로 따로 분리 할 수 있습니다.
Spring.Net은 XML 형식을 기본 설정 방식으로 이용하는데, 이를 App.Config에 설정 할 수 있으며 xml 파일에 저장 할 수도 있습니다.

MessageService.xml 이라는 파일을 생성하여 주시고, App.Config의 objects 섹션의 정보들을 MessageService.xml 에 넣어주신 후 App.Config context섹션의 resource 를 다음과 같이 수정하여 주시면 됩니다.
(App.Config의 objects 섹션은 삭제해 주세요.)

<context>

  <resource uri="file://MessageService.xml" />

</context>

테스트를 위해서는 MessageService.xml 파일의 속성 중 '출력 디렉토리로 복사' 를 '항상 복사' 로 바꿔주셔야 합니다.
실행하여 보시면 역시나 착실하게 실행되는 모습을 보실 수 있을 것입니다.

리소스는 uri에 따라 다르게 매핑되며 file, http(s), ftp, assembly 를 사용 할 수 있습니다.
assembly://MessageService/MessageService/MessageService.xml
http://www.mvpmagazine.net/MessageService.xml

지금까지의 예제에서 IApplicationContext 인스턴스 생성 시 IApplicationContext ctx = ContextRegistry.GetContext() 이 구문을 사용하였습니다.
이는 custom section 의 정보를 사용하여 초기화 하는 것입니다.
(더 정확히는 GetContext("contextName")과 같이 컨텍스트 이름을 주지 않을 시에는 기본 루트 컨텍스트(spring/context)를 가져오는 것입니다.)
그러나 App.Config과 같이 구성 파일에서만 리소스를 설정 할 수 있는 것은 아닙니다.
아래와 같이 XmlApplicationContext 를 이용하여 컨텍스트를 얻어 사용할 수도 있습니다. 

using (IApplicationContext ctx = new XmlApplicationContext("file://MessageService.xml"))

{

    MessageSender messageSender = (MessageSender)ctx.GetObject("MessageSender");

    messageSender.SendMessage("꽃미남에게 문자주세요");

}

 

Lazy initialization

lazy-init 속성은 객체의 로딩 시점을 나타냅니다.
singleton 객체에만 사용이 가능하며 true/false 에 따라 객체의 로딩 시점이 결정됩니다.
IApplicationContext 는 생성 시 singleton 객체들을 미리 생성하며, lazy-init 속성을 정의하지 않으면 IApplicationContext 생성 시 로딩(기본 속성은 false와 같음), lazy-init="true"로 설정하게 되면 객체 참조 시 로딩 합니다.

MessageService 프로젝트에 LazyBoy 클래스를 하나 추가한 후에 생성자에서 간단한 메시지를 찍는 코드를 넣겠습니다.

public class LazyBoy

{

    public LazyBoy()

    {

        Console.WriteLine("안녕하세요. LazyBoy 입니다.");

    }

}

그리고 다음 설정 파일에 다음 항목을 넣어주세요.

<object name="LazyBoy" type="MessageService.LazyBoy, MessageService"></object>

그리고 다음의 코드를 실행합니다.

using (IApplicationContext ctx = ContextRegistry.GetContext())

{

    Console.WriteLine("LazyBoy 생성 전");

    LazyBoy lazyBoy = (LazyBoy)ctx.GetObject("LazyBoy");

    Console.WriteLine("LazyBoy 생성 후");

}

IApplicationContext 생성시 singleton 객체들을 로딩하므로 객체가 로딩되어 생성자의 구문이 먼저 찍히게 됩니다.
다음과 같이 lazy-init을 true로 바꾸게 되면 명시적으로 객체를 참조할 때 생성되게 됩니다.

<object name="LazyBoy" type="MessageService.LazyBoy, MessageService" lazy-init="true"></object>

기본 lazy-init 속성값은 다음과 같이 미리 정의 할 수 있습니다. 

그렇다면 참조하는 객체가 lazy-init이 true 사용하는 객체가 false 라면 어떻게 될까요?
사용하는 객체가 생성 될 때 참조하는 객체도 같이 생성이 됩니다.
UseLazyBoy 클래스를 추가하고, App.Config도 다음과 같이 변경합니다.

UseLazyBoy.cs  

public class UseLazyBoy

{

    public LazyBoy LazyBoy { get; set; }

 

    public UseLazyBoy()

    {

        Console.WriteLine("안녕하세요. UseLazyBoy 입니다.");

    }

}

 

App.Config

<object name="LazyBoy" type="MessageService.LazyBoy, MessageService" lazy-init="true"></object>

 

<object name="UseLazyBoy" type="MessageService.UseLazyBoy, MessageService" lazy-init="false">

  <property name="LazyBoy" ref="LazyBoy"></property>

</object>

참고로 IObjectFactory는 singleton 객체의 로딩 시점이 IApplicationContext 와 다릅니다.
IObjectFactory는 객체 참조시에 로딩하는데요 lazy-init의 설정과 상관 없이 항상 객체 참조시에 로딩합니다.

Spring.Core.IO.IResource res = new Spring.Core.IO.FileSystemResource("MessageService.xml");

 

using (Spring.Objects.Factory.IObjectFactory ctx = new Spring.Objects.Factory.Xml.XmlObjectFactory(res))

{

    Console.WriteLine("LazyBoy 생성 전");

    LazyBoy lazyBoy = (LazyBoy)ctx.GetObject("LazyBoy");

    Console.WriteLine("LazyBoy 생성 후");

}

 

 

initialization method, destruction method

LifeCycle 인터페이스로 객체의 생성 직후, 파괴 전에 생성되는 메소드를 설정하는 속성입니다.
예시를 위하여 UseLazyBoy 클래스에 init, cleanup를 추가하고 App.Config도 변경하도록 하겠습니다.

UseLazyBoy.cs

public class UseLazyBoy

{

    public LazyBoy LazyBoy { get; set; }

 

    public UseLazyBoy()

    {

        Console.WriteLine("안녕하세요. UseLazyBoy 입니다.");

    }

 

    public void init()

    {

        Console.WriteLine("init() 입니다.");

    }

 

    public void cleanup()

    {

        Console.WriteLine("cleanup() 입니다.");

    }

}

 

App.Config

<object name="UseLazyBoy" type="MessageService.UseLazyBoy, MessageService" lazy-init="false" init-method="init" destroy-method="cleanup">

  <property name="LazyBoy" ref="LazyBoy"></property>

</object>

 

몇가지 기능을 소개해 드렸는데요, 이 외에도 많은 기능들이 있으므로 레퍼런스를 찾아보시기를 바라며, 하나하나의 기능들을 세세히 습득하시기 보다는 넓게 생각하셔서 활용해 보시는 것이 좋을 것 같습니다.

이제 곧 5월의 황금 연휴가 시작되네요.
모든 분들 좋은 연휴 보내시고 즐거운 일만 생기시길 바라겠습니다.

평점 5.0 / 2회 참여

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments

Add comment


 

biuquote
Loading



Search

Recent comments