ASP.NET2009.04.15 18:07
당연히 잘 되겠지 라는 생각을 하며, 이 글을 쓰려고 자료 찾고 시행착오 겪고 한게 벌써 8시간 째다.
자료가 이렇게도 없다니 ㅠㅠ, 아마 ASP.NET MVC 에 SPRING.NET 의 Facade 패턴의 DI 를 직접 구현 한 첫번째 글이 될것 같다. ㅡㅡ; 약간 비슷한 자료는 많이 찾았는데, 구현 하고자 하는 자료가 없어서 엄청 애 먹었다.

이전 강좌에서 참조 추가를 했는데, 몇개가 빠져 다시 확실하게 추가 하고 넘어가자.
참조 추가 하는 방법은 아니깐 참조된 파일만 나열하자면... 우선 일반적으로 SPRING.NET 을 설치 하였다면 참조할 경로는 C:\Program Files\Spring.NET 1.2.0\bin\net\2.0\release 이다. 여기서,

antlr.runtime.dll
Common.Logging.dll
Spring.Aop.dll
Spring.Core.dll
Spring.Web.dll

이렇게 다섯개를 참조 하면된다. antlr.runtime 은 아직 잘 모르겠고, 하다보면 뭐 하는 녀석인지 알게 되겠지.. ㅡㅡ; 참고로 www.antlr.org 에 가면 자세한 설명이 있다.

Common.Logging 은 원래 스프링이 자바버전에는 미니 Log4j 를 가지고 있다. 마찬가지로, 스프링 프레임웍으로 개발을 할때 스프링 자체적으로 뱉어내는 로그 들을 확인해 보기 위해 추가 한다. 안해도 상관없지만, 자동으로 콘솔창에 로그가 찍히는걸 보고 싶으면 추가!!

이렇게 추가 했으면, 처음으로 해야 할 것이 web.config 를 수정해야 하는 일이다.


... 이라고 된 부분은 프로젝트 생성할때 만들어 지는 코드 이므로, 해당 섹션에 맞게 위 코드를 추가 하면 된다.

그리고 web.config 와 같은 위치에 objects.xml 이라는 파일을 하나 생성 하고 코드는 아래와 같이 넣는다.


폴더 구조가 아래 그림과 같도록 Service 폴더를 하나 추가 한다. 추가 후에 SpringBoardFacade.vb 라는 인터페이스와 SpringBoardImpl.vb 클래스, SpringControllerFactory.vb 클래스를 만든다.

SpringBoardFacade.vb 는 아래와 같다.


SpringBoardImpl.vb 는 아래와 같다.


SpringControllerFactory.vb 는 아래와 같다.


그리고, Global.asax 의 Application_Start() 메서드에 다음과 같이 한줄을 추가 하도록 한다.

위 세 코드를 설명하자면, 우선 SpringBoardFacade 인터페이스는 SpringBoardImpl 클래스의 인터페이스 이다. SpringBoardImpl 클래스는 Facade 패턴에 쓰일 가장 중요한 클래스 이고, iBATIS.NET 과 연동할때 중심이 될 클래스 이다.
코드에 그냥 Test() 라는 메서드 하나를 둔게, ASP.NET MVC 에서 라우팅을 통해 컨트롤러로 갔을때 제대로 DI 가 되는지 테스트 해 보기 위해서 넣은 코드이다. 실제 게시판 코딩할때는 삭제 될 메서드 이다.

마지막으로 SpringContrllerFactory 클래스는 Global.asax 에서 어플리케이션 스타트 할때 objects.xml 을 미리 로드 하기 위한 System.Web.Mvc.IControllerFactory 구현부 이다.

그럼 마지막으로, HomeController.vb 를 다음과 같이 수정한다.

SPRING Framework 이나 오픈소스 프레임웍의 가장 단점이 세팅하기가 정말 어렵다는 점인데, 역시나 오늘 하루 출근해서 계속 요것만 한것 같다. ㅠㅠ

이렇게 코딩을 하고, 세팅한 이유는 위 HomeController 클래스의 19번째줄 Debug.Pring(sbFacade.Test()) 요게 제대로 나오는지 테스트 한 것이였다. ㅡ..ㅡ;
 
ASP.NET MVC 위에서 MVC 흐름을 자연스럽게 타면서, SPRING.NET 의 Core 부분의 DI를 구현 해 본것이다.

실행후 직접 실행창에 다음과 같은 로그가 찍히면 성공!!


사실 여기 까지의 셋팅이 자바에서도 마찬가지로 굉장히 힘들었던 부분이다.

다음 포스팅에서는 iBATIS.NET 을 붙이는 작업을 하도록 해야겠다.
저작자 표시 비영리 동일 조건 변경 허락
신고
Posted by dotnetpower
Spring.NET2009.04.10 16:09

어떤이는 OOP가 발전되어서 AOP가 되었다 라고 하는데 맞을수도 있고 아닐수도 있다. 내 생각엔 오른손이 하는것을 왼손은 거들뿐!! OOP는 오른손, AOP는 왼손. ㅋㅋ 썰렁한가?

암튼.. 험...

Aspect 하기 좋은 기능중 하나가 DI인데 기존 방식이랑 다른점이 무었인지 코드로 직접 실행 해 보자.
어떻게 Coupling을 줄일 수 있는지...

우선 기존에 어떻게 클래스를 호출하는지 왜 Dependency가 강하게 결합이 되는지 기존 방식대로 해 보자.

VS를 열고 새프로젝트를 선택한 다음 이름이 oldClass라는 콘솔 응용 프로그램을 생성 하도록 하자.
아래와 같이 Person.vb 클래스를 하나 만들자


콘솔용이니깐, 모듈에서 시작하므로 Module1.vb 코드를 아래와 같이 입력하자.

코딩끝!

이제 F5를 과감하게 눌러 실행 해 보자. 아래와 같은 화면이 나타날것이다.

이것이 우리하 흔히 알고 사용하는 OOP 방식이다. 하지만, 코드상에서 Moonhyuk = new Person 이라고 부르는 순간 이미 Dependency 가 강하게 결합되어 버린다.

그럼 SPRING.NET으로 결합도를 낮춰 보자. spring.net 이 설치가 안되어 있으면 http://www.springframework.net 에서 받을수 있다.
새 항목 추가를 하여 응용 프로그램 구성 파일(app.config)를 추가 한다. 추가된 app.config의 내용을 아래와 같이 변경하자.



그리고 프로젝트 참조를 추가 해야 한다. SPRING.NET에서 핵심 영역과 DI 부분을 제공해 주는 Spring.Core.dll 을 추가 하자
일반적으로 설치 했다면 경로는 C:\Program Files\Spring.NET 1.2.0\bin\net\2.0\release 이다.

그리고, 종속성을 제거하기 위해 IPerson.vb 인터페이스를 하나 만든다.


Person 클래스가 인터페이스를 구현 하기 때문에 기존 코드를 아래와 같이 수정한다.


마지막으로 Module1.vb 를 수정한다.



실행해 보면 아래와 같은 화면이 잘 나타난다.


훌륭하지 않은가? 종속성을 제거 하면서, Person 클래스를 config 파일에 설정해 두고 주입시킨것이다.
실제로 컴파일 시점에서 컨텍스트가 로드 될때 이미 spring framework 에서는 <object id="person" type="oldClass.Person, oldClass"> 를 인스턴스화 시켜 버린다. 즉, Module1.vb 에서 생성시키는것이 아니라 SPRING.NET 에서 생성 시켜 두었다가 가져다 쓸 뿐이다.

SPRING.NET은 훌륭한 .NET Framework 을 거들뿐... ㅎㅎ
저작자 표시 비영리 동일 조건 변경 허락
신고
Posted by dotnetpower
Spring.NET2009.04.09 10:09
OOP(Object Oriented Programming)의 우수함과 유연성 덕분에 프로그래밍 언어는 대부분이 이와 같은 성격을 띄고 있다.
객체지향이 완벽할것이라 생각을 했지만, 어플리케이션의 덩치가 커질수록 어쩔수 없는 결합도(Coupling)가 생겨 버린다.
결합도 라는 말은 모듈들 사이의 관계를 말한다. 모듈이 독립적일수록 결합도가 낮다고 말할수 있고, 결합도가 낮을수록 좋은 프로그램 이라고 말한다. 느슨하게 결합된 디자인은 변경사항이 생겨도 큰 무리 없이 수정이 가능 해 진다.

하지만, 결합도 라는것은 아무리 느슨한 결합도(Loose Coupling)를 유지해도, 런타임시에 요청 -> 응답 까지는 연결될수 밖에 없다. 결합도를 조금이라도 낮추기 위해서 인터페이스를 사용하는데 이걸로도 해결되지 않는 문제가 있다.

DI는 보통 역제어(inversion of control) 이라는 이름으로 2004년 Martin Fowler에 한 논설에서 제어의 어떤 측면이 역전(invert)되는지 의문을 가지고 구체적으로는 종속객체를 획득하는 부분이 역전된다는 결론을 내리고 "종속객체 주입" 이라는 용어를 고안해 내었다고 한다. -Spring in Action 참고-


보통 위 그림처럼 ClassA는 ServiceA, ServiceB와 결합도를 유지 하게 된다.

이렇게 설계가 되었을때 다음과 같은 상황이 발생되어진다.
  • 관계가 변경되거나 수정되어야 할때 반드시 소스코드를 수정해야한다.
  • 컴파일 될때 관계가 겹합되어 버린다.
  • 단위 모듈별 테스트를 하기 어렵다.
  • 클래스 들이 반복적으로 생성되고, 재 배치된다.


그렇다면 DI를 사용하면 어떻게 결합도를 낮출수 있을까?
이에 대해 해결할수 있는 방법은 객체를 주입 시켜 버리면 된다. 아래 그림 참고.


우선 Builder라는것은 컴파일 되는 시점이라 생각하면 될것 같다.
컴파일 될때 ClassA를 생성시키고, ClassA는 ServiceA, ServiceB 의 인스턴스를 생성하는 것이 아니라  생성시점에서 Builder로 부터 주입되어진다. 그리고 나서 사용 할때는 Service들의 인터페이스를 통새 주입되어진 Service들을 사용 할 수 있다. 이것이 바로 역제어(inversion of control) 라 한다.

보통 Dependency Injection 를 위해서는 다음과 같은 방법이 존재 한다.

  • 생성자를 이용한 의존성 삽입(Constructor Injection)
  • Setter() 메소드를 이용한 의존성 삽입(Setter Injection)
  • 초기화 인터페이스를 이용한 의존성 삽입(Interface Injection)



참고

저작자 표시 비영리 동일 조건 변경 허락
신고
Posted by dotnetpower
TAG DI

티스토리 툴바