Spring.NET 프레임워크활용가이드 Version 0.2 엔소아컨설팅대표컨설턴트전병선
Spring.NET 프레임워크활용가이드 애플리케이션프레임워크 Spring.NET 프레임워크 IoC 컨테이너와 DI AOP (Aspect-Oriented Programming)
애플리케이션프레임워크 프레임워크 (framework) 틀구조, 뼈대, 골격, 구조, 구성 애플리케이션프레임워크 (application framework) 애플리케이션을구축하고설계할수있도록도와주는틀구조 프레임워크는소프트웨어의특정한클래스에대하여재사용할수있는설계로구성된관련된클래스들의집합이다. 프레임워크는설계를추상적인클래스로분리하고그들의책임과협동관계를정의함으로써아키텍처적인가이드를제공한다. 여러분은프레임워크로부터추상적인클래스를서브클래싱하여애플리케이션에특정한서브클래스를생성함으로써특정한애플리케이션에대하여프레임워크를커스터마이징한다 - GoF(gang of four) 의 Design Patterns
애플리케이션프레임워크 공통라이브러리!= 프레임워크 제어의역흐름 (IoC, inversion of control) 헐리우드원칙 (Hollywood Principle) : 나를부르지마라. 내가너를부를것이다 Don t call me, I ll call you. 프레임워크코드가전체애플리케이션의처리흐름을제어하며, 특정한이벤트가발생할때다형성 (polymorphism) 을통해애플리케이션이확장한메서드를호출함으로써제어가프레임워크로부터애플리케이션으로거꾸로흐르게한다.
애플리케이션프레임워크 프레임워크의이점 모듈화 (modularity) 프레임워크는구현을인터페이스뒤에감추는캡슐화를통해서모듈화를강화한다. 프레임워크의모듈화는설계와구현의변경에따르는영향을국소화함으로써손쉽게소프트웨어의품질을향상시킬수있게한다 재사용성 (reusability) 프레임워크가제공하는인터페이스는여러애플리케이션에서반복적으로사용할수있는일반적인컴포넌트를정의할수있게함으로써재사용성을높여준다. 프레임워크재사용성은도메인지식과경험있는개발자들의이전의노력을활용하여, 애플리케이션의요구사항과소프트웨어설계에대한공통의솔루션을반복적으로재개발하고그에대해유효성을다시확인하는작업을피할수있게한다. 프레임워크컴포넌트를재사용하는것은소프트웨어의품질, 성능, 신뢰성, 상호운용성을향상시킬뿐만아니라, 프로그래머의생산성을상당히높여준다. 확장성 (extensibility) 프레임워크는다형성 (polymorphism) 을통해애플리케이션이프레임워크의인터페이스를확장할수있게한다. 프레임워크확장성은새로운애플리케이션서비스와특성을커스터마이징하는것을보장하는데있어서필수적인사항이며, 또한프레임워크를애플리케이션의가변성으로부터분리함으로써재사용성의이점을얻게한다.
애플리케이션프레임워크 프레임워크개념의진화과정
애플리케이션프레임워크 프레임워크레이어 (framework layer) 많음 비즈니스애플리케이션 비즈니스지식의정도 애플리케이션프레임워크도메인프레임워크레이어범용프레임워크레이어시스템프레임워크 (.NET, Java) 적음 운영체제 (Windows, Linux)
애플리케이션프레임워크 프레임워크레이어 (framework layer) 시스템프레임워크 (system framework) 파운데이션프레임워크 (foundation framework) 애플리케이션과애플리케이션프레임워크에프로그래밍모델을제공하는프레임워크 OMG 의 CORBA Sun MicroSystems 의 J2EE Microsoft 의.NET 프레임워크나 COM/DCOM 도메인프레임워크 (domain-specific framework) 특정한비즈니스도메인을대상으로하는프레임워크컴포넌트로구성된다 특정한비즈니스도메인의모든애플리케이션에공통된비즈니스지식을구현한다 범용프레임워크 (cross-domain framework) 비즈니스도메인에관계없이대부분의애플리케이션에서공통적으로발견될수있는컴포넌트와서비스로구성된다 Struts, Spring, Spring.NET, Microsoft 의 Enterprise Library, Application Block
애플리케이션프레임워크 공통스팟과핫스팟 프레임워크개발은대상애플리케이션에서공통성 (commonality) 과가변성 (v ariability) 를분석하는것에서부터시작한다 공통스팟 (common spot) 애플리케이션에서공통성이반복해서나타나는위치 공통스팟의공통적인부분은프레임워크컴포넌트안에구현한다 핫스팟 (hot spot) 애플리케이션에서가변적인위치 애플리케이션마다가변적이어서프레임워크를커스터마이징할수있는위치 핫스팟은나중에애플리케이션이커스터마이징하여채워넣을수있도록비워둔다. 각애플리케이션은프레임워크에있는핫스팟위치에고유한기능을구현하여끼워넣음으로써프레임워크가각애플리케이션마다서로다르게행위를하게한다
애플리케이션프레임워크 프레임워크구현기법 화이트박스프레임워크 (white-box framework) 블랙박스프레임워크 (black-box framework) 그레이박스프레임워크 (gray-box framework)
애플리케이션프레임워크 화이트박스프레임워크 (white-box framework) 추상클래스 (abstract class) 로구성 템플릿메서드 (template method) 후크메서드 (hook method)
애플리케이션프레임워크 화이트박스프레임워크 (white-box framework) 후크메서드 (hook method) 애플리케이션고유의로직을채워넣은핫스팟으로서의역할을한다 가상함수 (virtual function) 로구현한다 템플릿메서드 (template method) 템플릿메서드는특정한오퍼레이션의프로세스흐름을기술하며공통스팟으로서의역할을한다
애플리케이션프레임워크 화이트박스프레임워크 (white-box framework) 장점 단점 구현하기쉽다 템플릿메서드에프로세스의흐름이고정되어있어유연성이부족하다 개발자가프레임워크내부의세부사항을잘알고있어야후크메서드를구현할수있다
애플리케이션프레임워크 블랙박스프레임워크 (black-box framework) 인터페이스 (interface) 로구성 핫스팟 (hot spot)
애플리케이션프레임워크 블랙박스프레임워크 (black-box framework) 장점 단점 내부구현을알필요가없다 더큰유연성을제공할수있다 구현하기어렵다 유연성을확보하기위해서는애플리케이션이템플릿메서드를구현해야하는경우도있다
애플리케이션프레임워크 그레이박스프레임워크 (gray-box framework) 화이트박스프레임워크와블랙박스프레임워크의장단점을혼합
애플리케이션프레임워크 그레이박스프레임워크 (gray-box framework)
Spring.NET 프레임워크활용가이드 애플리케이션프레임워크 Spring.NET 프레임워크 IoC 컨테이너와 DI
Spring.NET 프레임워크 Spring.NET 객체의라이프사이클을관리하기위하여 Dependency Injection(DI) 를사용하는경량 (lightweight) 컨테이너 엔터프라이즈급.NET 애플리케이션개발을위한애플리케이션프레임워크 J2EE 애플리케이션개발을위해만든자바진영의 Spring 프레임워크를닷넷환경에맞도록포팅하되 ASP.NET, Persistence,.NET Remoting 등의닷넷기술을적극활용함
Spring.NET 프레임워크 Spring.NET 프레임워크의주요모듈 Web Extensions AJAX Testing NUnit Web ASP.NET Framework Services Portable Service Abstractions Core IoC Container + Base Functionality NHibernate Data DAO/TX Management AOP
Spring.NET 프레임워크 Spring.NET 프레임워크가제공하는기능들 DI(dependency injection) AOP(aspect-oriented programming) 데이터액세스지원 : ORM(object-relation mapping) 프레임워크인 NHibernate 지원을포함 웹프레임워크 통합테스팅 동적리플렉션 (dynamic reflection) 스레딩 (threading) 및동시성 (concurrency) 객체풀링 (object pooling) 표현식평가 (expression evaluation) 서비스 기타
Spring.NET 프레임워크 Spring.NET 프레임워크의장점 모듈화및이해하기쉬움 코드를테스트하기쉬움 일관성있는데이터액세스프레임워크를제공함 일관성있는구성 (configuration) 확장하기쉬움 처음부터하지않아도됨
IoC 컨테이너와 DI Web Extensions AJAX Testing NUnit Web ASP.NET Framework Services Portable Service Abstractions Core IoC Container + Base Functionality NHibernate Data DAO/TX Management AOP
IoC 컨테이너와 DI 다음코드를생각해보자 public class A { public B cb; // A 는 B 에종속된다 public A() { cb = get_b_object(...); }... } public class B {... } public class Container { public A createa() { return new A(); } } 문제점 A 는 B 인스턴스를생성하는방법에종속된다
IoC 컨테이너와 DI 종속성제거 public class A { protected B b1; // A 는 B 에종속된다 protected B b2; public A(B b1) { this.b1 = b1; } // dependency injection public B B2 { set { this.b2 = value; } } // dependency injection... } public class B {... } public class IoCContainer { public A createa() { B b1 = get_b_object(...); A a = new A(b1); // constructor injection B b2 = get_b_object(...); a.b2 = b2; // setter aka property injection return a; } }
IoC 컨테이너와 DI DI(Dependency Injection) <object id = a type= A > <set-prop ref= b > </object> <object id = b type = B /> 종속성구성 IoC 컨테이너 class A { protected B _b; public B b { set { b = value;} } } 실제구현
첫번째 Spring.NET 애플리케이션 프로젝트생성 HelloApp 콘솔애플리케이션
첫번째 Spring.NET 애플리케이션 Hello 클래스생성
첫번째 Spring.NET 애플리케이션 Hello 클래스구현 // 파일명 : Hello.cs using System; using System.Collections.Generic; using System.Text; namespace HelloApp { class Hello { public string sayhello(string name) { return " 안녕하세요? " + name + " 씨!"; } } }
첫번째 Spring.NET 애플리케이션 Spring.NET 프레임워크참조 Spring.core.dll
첫번째 Spring.NET 애플리케이션 애플리케이션구성파일생성
첫번째 Spring.NET 애플리케이션 구성설정 // 파일명 : App.config <?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> <!-- using section in App.config --> <resource uri="config://spring/objects"/> </context> <objects xmlns="http://www.springframework.net" > <description> 첫번째 Spring.NET 애플리케이션 </description> <object id="myhello" type="helloapp.hello, HelloApp"> </object> </objects> </spring> </configuration>
첫번째 Spring.NET 애플리케이션 Hello 클래스사용 // 파일명 : Program.cs using System; using System.Collections.Generic; using System.Text; using Spring.Context; using Spring.Context.Support; namespace HelloApp { class Program { { static void Main(string[] args) { IApplicationContext ctx = ContextRegistry.GetContext(); Hello hello = (Hello)ctx.GetObject("MyHello"); string name = " 전병선 "; string result = hello.sayhello(name); Console.WriteLine(result); } } }
첫번째 Spring.NET 애플리케이션 HelloApp 애플리케이션실행
첫번째 Spring.NET 애플리케이션 구성과코드 MyHello 객체정의 // 파일명 : App.config <?xml version="1.0" encoding="utf-8"?> <configuration> namespace HelloApp <configsections> { <sectiongroup name="spring"> class Hello <section name="context" type="spring.context.support.contexthandler, { Spring.Core"/> public string sayhello(string name) <section name="objects" type="spring.context.support.defaultsectionhandler, Spring.Core" /> </sectiongroup> { </configsections> return " 안녕하세요? " + name + " 씨!"; <spring> } <context> } <!-- using section in App.config --> } <resource uri="config://spring/objects"/> </context> <objects xmlns="http://www.springframework.net" > <description> 첫번째 Spring.NET 애플리케이션 </description> <object id="myhello" type="helloapp.hello, HelloApp"> </object> </objects> </spring> </configuration> // 파일명 : Hello.cs using System; using System.Collections.Generic; using System.Text;
첫번째 Spring.NET 애플리케이션 구성과코드 MyHello 객체사용 // 파일명 : App.config // 파일명 : Program.cs using System; using System.Collections.Generic; using System.Text; using Spring.Context; using Spring.Context.Support; <?xml version="1.0" encoding="utf-8"?> <configuration> <configsections> <sectiongroup name="spring"> <section name="context" type="spring.context.support.contexthandler, namespace HelloApp { Spring.Core"/> <section name="objects" type="spring.context.support.defaultsectionhandler, class Program { { Spring.Core" /> </sectiongroup> </configsections> <spring> <context> <!-- using section in App.config --> <resource uri="config://spring/objects"/> </context> } <objects xmlns="http://www.springframework.net" } > <description> 첫번째 Spring.NET 애플리케이션 } </description> <object id="myhello" type="helloapp.hello, HelloApp"> </object> </objects> </spring> </configuration> static void Main(string[] args) { IApplicationContext ctx = ContextRegistry.GetContext(); Hello hello = (Hello)ctx.GetObject("MyHello"); string name = " 전병선 "; string result = hello.sayhello(name); Console.WriteLine(result);
첫번째 Spring.NET 애플리케이션 IHello 인터페이스도입 Hello 클래스와 Program 클래스사이의종속성제거 // 파일명 : IHello.cs using System; using System.Collections.Generic; using System.Text; namespace HelloApp { interface IHello { string sayhello(string name); } }
첫번째 Spring.NET 애플리케이션 IHello 인터페이스도입 Hello 클래스와 Program 클래스코드변경 // 파일명 : Hello.cs using System; using System.Collections.Generic; using System.Text; namespace HelloApp { class Hello : IHello { public string sayhello(string name) { return " 안녕하세요? " + name + " 씨!"; } } } // 파일명 : Program.cs using System; using System.Collections.Generic; using System.Text; using Spring.Context; using Spring.Context.Support; namespace HelloApp { class Program { { static void Main(string[] args) { IApplicationContext ctx = ContextRegistry.GetContext(); IHello hello = (IHello)ctx.GetObject("MyHello"); string name = " 전병선 "; string result = hello.sayhello(name); Console.WriteLine(result); } } }
첫번째 Spring.NET 애플리케이션 Hello 컴포넌트도입 Hello 클래스의기능을 HelloApp 애플리케이션으로부터분리하여별도의라이브러리로구현 HelloApp 애플리케이션과 Hello 컴포넌트사이의종속성제거
첫번째 Spring.NET 애플리케이션 IHello 인터페이스컴포넌트 IHello 인터페이스정의 // 파일명 : IHello.cs using System; using System.Collections.Generic; using System.Text; namespace Hello { interface IHello { string sayhello(string name); } }
첫번째 Spring.NET 애플리케이션 Hello 구현컴포넌트 IHello 인터페이스실현 // 파일명 : Hello.cs using System; using System.Collections.Generic; using System.Text; namespace Hello { class Hello : IHello { public string sayhello(string name) { return " 안녕하세요? " + name + " 씨!"; } } }
첫번째 Spring.NET 애플리케이션 HelloApp 애플리케이션 IHello 인터페이스를통해 Hello 컴포넌트사용 // 파일명 : Program.cs using System; using System.Collections.Generic; using System.Text; using Spring.Context; using Spring.Context.Support; using Hello; namespace HelloApp { class Program { { static void Main(string[] args) { IApplicationContext ctx = ContextRegistry.GetContext(); IHello hello = (IHello)ctx.GetObject("MyHello"); string name = " 전병선 "; string result = hello.sayhello(name); Console.WriteLine(result); } } }
첫번째 Spring.NET 애플리케이션 HelloApp 애플리케이션의 Hello 컴포넌트참조 // 파일명 : App.config <?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> <!-- using section in App.config --> <resource uri="config://spring/objects"/> </context> <objects xmlns="http://www.springframework.net" > <description> 첫번째 Spring.NET 애플리케이션 </description> <object id="myhello" type="hello.hello, Hello"> </object> </objects> </spring> </configuration>
AOP (Aspect-Oriented Programming) Web Extensions AJAX Testing NUnit Web ASP.NET Framework Services Portable Service Abstractions Core IoC Container + Base Functionality NHibernate Data DAO/TX Management AOP
AOP (Aspect-Oriented Programming) 시스템설계 / 개발중에늘만나게되는문제들 로깅 (Logging) 보안 / 인증 (security/authentication) 트랜잭션 (transaction) 리소스풀링 (resource pooling) 에러검사 (error checking) 정책적용 (policy enforcement) 멀티쓰레드안전관리 (multithread safety) 데이터퍼시스턴스 (data persistence) 객체지향설계에의해핵심요구사항과기능들을클래스 / 컴포넌트들에잘모듈화하였지만여전히공통적으로나타나는문제들을어떻게처리할것인가?
횡단관심 (Cross-cutting Concerns) AOP (Aspect-Oriented Programming) OOP 로횡단관심사들을해결할수있을까? AOP 는 OOP 를대체할수있을까? 핵심관심 (core concerns) 계좌조회계좌이체입 / 출금이자계산신용도조회 Logging Security Transaction
AOP (Aspect-Oriented Programming) 관점지향프로그래밍이란? 관심의분리 (Separation of Concern) 를통해문제영역 (problem domain) 을핵심관심사 (core concerns) 와횡단관심사 (cross-cutting concerns) 의독립적모듈로분해하는프로그래밍패러다임. 장점 관심의분리 (Separation of Concern) 를이끌어낸다. 비즈니스로직에대한이해도를높일수있다. 생산성을향상시킨다. 비즈니스코드와횡단관심사들간의결합을없앤다. 비즈니스코드의재사용성을높인다. 확장이용이하다.
AOP (Aspect-Oriented Programming) AOP 기본용어 cross-cutting concerns 보안, 로그, 인증과같이시스템에전반적으로산재된기능들 Aspect 포인트컷 ( 어디에서 ) 과어드바이스 ( 무엇을할것인지 ) 를합쳐놓은것. Joinpoint 횡단관심모듈의기능이삽입되어동작할수있는실행가능한특정위치. Advice/interceptor 각조인포인트에삽입되어져동작할수있는코드 Pointcut 어떤클래스의어느조인포인트를사용할것인지를결정하는선택기능 Weaving / 크로스컷팅 포인트컷에의해서결정된조인포인트에지정된어드바이스를삽입하는과정 참고 : http://www.zdnet.co.kr/builder/dev/java/0,39031622,39147106,00.htm
두번째 Spring.NET 애플리케이션 프로젝트생성 AOPExample1 콘솔애플리케이션
두번째 Spring.NET 애플리케이션 참조추가 Spring.Aop.dll
두번째 Spring.NET 애플리케이션 핵심관심사를수행하는컴포넌트를위한인터페이스생성 ICommand.cs
두번째 Spring.NET 애플리케이션 핵심관심사를수행하는컴포넌트를위한클래스생성 ServiceCommand.cs
두번째 Spring.NET 애플리케이션 횡단관심사를처리하는 Advice 생성 (around advice) ConsoleLoggingAroudAdvice.cs
두번째 Spring.NET 애플리케이션 Weaving 작업
두번째 Spring.NET 애플리케이션 실행결과
두번째 Spring.NET 애플리케이션 Configuration 이용하기 (App.config 파일 )
두번째 Spring.NET 애플리케이션 Configuration 이용하기 참조추가 : Spring.Core.dll
두번째 Spring.NET 애플리케이션 Configuration 이용하기 ProxyFactory 대신 context 사용하기
두번째 Spring.NET 애플리케이션 실행결과
두번째 Spring.NET 애플리케이션 Configuration 분석 1. 적용할 Advice 를 ConsoleLoggingAroundAdvice 라는이름의객체로등록. 2. Advice 를적용할대상은 ServiceCommand 타입이며 myserviceobjecttarget 이라는객체이름으로 myservicecommand 객체에등록된다. 3. 등록된 Advice 는 myservicecommand 객체의타겟에대하여 interceptor 로서동작한다.
두번째 Spring.NET 애플리케이션 Configuration 분석
두번째 Spring.NET 애플리케이션 특정메서드에만 Advice를적용하려면? 특정문자열로시작하는메서드들에만 Advice를적용하려면? 예 ) LogXXX(), LogYYY(), LogZZZ() 메서드에서는로그를남기고싶다. IPointcut 인터페이스활용
두번째 Spring.NET 애플리케이션 AOPExample2 프로젝트 1. C# Console Application 생성 2. AOPExample1 프로젝트에서파일복사 ConsoleLoggingAroundAdvice.cs ICommand.cs ServiceComponent.cs 3. 참조추가 Spring.Aop.dll Spring.Core.dll
두번째 Spring.NET 애플리케이션 AOPExample2 프로젝트 ICommand 인터페이스에메서드추가
두번째 Spring.NET 애플리케이션 AOPExample2 프로젝트 ServiceComponent 클래스수정
두번째 Spring.NET 애플리케이션 AOPExample2 프로젝트 ProxyFactory 에 Advice 적용하기 : Do 로시작하는메서드에만..
두번째 Spring.NET 애플리케이션 AOPExample2 프로젝트 실행결과 Execute() 메서드 : Advice 적용되지않았음 DoExecute() 메서드 : Advice 가적용되었음.
두번째 Spring.NET 애플리케이션 AOPExample2 프로젝트 구성설정이용하여실행
To be continued Web Extensions AJAX Testing NUnit Web ASP.NET Framework Services Portable Service Abstractions Core IoC Container + Base Functionality NHibernate Data DAO/TX Management AOP
감사합니다! 전병선 ( 田炳善 ) 엔소아컨설팅그룹대표이사 IT 아키텍트 / 컨설턴트 bsjun@ensoa.co.kr 010-2059-4845 70