'PP/SPRING.NET'에 해당되는 글 4건

  1. 2012.01.13 일반 구성 설정(ASP.NET)
  2. 2012.01.12 Spring .Net 활용 가이드
  3. 2012.01.10 DI
  4. 2012.01.10 서론.
posted by 방랑군 2012. 1. 13. 01:07


참조 : http://msdn.microsoft.com/ko-kr/library/ms228112.aspx

'PP > SPRING.NET' 카테고리의 다른 글

Spring .Net 활용 가이드  (0) 2012.01.12
DI  (0) 2012.01.10
서론.  (0) 2012.01.10
posted by 방랑군 2012. 1. 12. 20:06



Spring .Net 프레임워크 활용 가이드입니다

  • 애플리케이션 프레임워크
  • Spring.NET 프레임워크
  • IoC 컨테이너와 DI
  • AOP (Aspect-Oriented Programming)

좋은 자료들을 틈나는대로 업데이트 할 예정입니다

많은 관심 부탁드립니다^^

'PP > SPRING.NET' 카테고리의 다른 글

일반 구성 설정(ASP.NET)  (0) 2012.01.13
DI  (0) 2012.01.10
서론.  (0) 2012.01.10

DI

posted by 방랑군 2012. 1. 10. 00:06

spring.NET

스프링 닷넷은 자바 진영에서 매우 다양한 곳에서 쓰이고 있는 유명한 프레임워크 스프링의 닷넷 버전이다. 아래의 그림을 보면 알 수 있듯이 단순한 컨버젼이 아니라 스프링이 가지고 있는 개념을 닷넷에 가장 어울리도록 최적화한 것이라고 볼 수 있다.

springnet.png

여기서는 이런 다양한 스프링 닷넷 프레임워크 중 DI에 대해서 간략하게 알아보겠다.(이 부분은 코어에 소속된 부분이다. 즉 스프링의 다양한 개념 중에서도 매우 중요하며 기초적인 부분이다.)

DI

먼저 DI라는 개념을 먼저 파악해야 한다. DI는 Dependency Injection의 약자로서 번역하면 의존성 주입 정도가 된다. 간략하게 설명하자면 하나의 클래스에서 다른 클래스의 객체를 사용할 경우에 직접 객체를 생성해서 사용하지 않고 사전에 설정해 둔 바에 따라서 객체를 가져와 사용할 수 있게 한다는 개념이다.

이렇게 할 경우의 가장 큰 장점은 가져오는 객체의 구조나 생성방식이 바뀌더라도 설정파일을 바꾸는 것만으로 그에 무관하게 사용할 수 있다는 점이다.

아래의 간단한 예를 보면 쉽게 이해가 되리라 생각한다.


스프링 닷넷에서 DI의 사용

먼저 사전작업으로 Spring.Net 프레임워크를 다운받아 설치해두는 작업이 필요하다.(이는 스프링닷넷 프레임워크 사이트에서 다운받아 설치만 하면 되므로 생략)

그리고 Spring.Core 어셈블리 파일을 참조추가해둔다. 이로서 사전 작업은 끝

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Spring.Context;
using Spring.Context.Support;

namespace SpringNET
{
class Program
{
static void Main(string[] args)
{
IApplicationContext ctx = ContextRegistry.GetContext();
Hello hello = (Hello)ctx.GetObject("MyHello");
string name = "lee";
string result = hello.SayHello(name);
Console.WriteLine(result);
Console.Read();
}
}
class Hello
{
public string SayHello(string name)
{
return "Hello!, " + name;
}
}
}


위와 같이 소스코드를 하나 작성한다. 다른 부분은 간단하므로 설명하지 않고 DI가 실제로 일어나는 붉은 색부분만 설명하면 첫번째 줄은 현재 어셈블리의 설정파일로 부터(아래에 작성해 볼 것이다.) 어플리케이션 컨텍스트를 가져온다. 둘째줄은 가져온 컨텍스트에서 MyHello라는 이름의 Object를 가져오도록 하는 것이다.

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>
<resource uri="config://spring/objects" />
</context>

<objects xmlns="http://www.springframework.net">

<object name="MyHello" type="SpringNET.Hello, SpringNET">
</object>
</objects>
</spring>
</configuration>


위의 파일은 해당 어셈블리의 설정파일과 같은 것이다. 여기에 스프링에 관한 설정도 넣을 수 있다.

다른 부분은 무시하고 핵심적인 부분만 설명하면 붉은 색의 코드 한 줄이 의존성 주입이 가능하도록 해주는 부분이다. 객체의 이름은 MyHello, 클래스형은 SpringNET.Hello이며 해당 객체가 들어있는 어셈블리의 이름은 SpringNET라는 이야기이다.

간단히 스프링 닷넷의 DI를 살펴보았다. 좀더 자세한 것은 스프링 닷넷의 다른 기능을 봐가며 살펴보도록 하겠다.


참고자료: spring-net-reference.pdf Spring.NET_guide_ensoa_v.0.2.pdf

'PP > SPRING.NET' 카테고리의 다른 글

일반 구성 설정(ASP.NET)  (0) 2012.01.13
Spring .Net 활용 가이드  (0) 2012.01.12
서론.  (0) 2012.01.10
posted by 방랑군 2012. 1. 10. 00:00
출처 :   http://dncblog.tistory.com/53 

Spring은 이미 오래전부터 자바진영에서 각광받고 있는 프레임웤으로서, 닷넷버전으로도 공개가 되었습니다. 
그것이 바로, Spring.NET인데요,   
Spring.NET은 닷넷기반의 엔터프라이즈 어플리케이션을 구축하기 위한 어플리케이션 프레임웤  이라고 정의할 수 있습니다. 



Spring.NET의 각 모듈의 구성을 보시면, 하단 우측의 AOP 기반으로, ASP.NET,  Web Serivce, ORMapping, DataAccess, NUnit, Remoting, COM+ 등의 다양한 코어 모듈 기반의 프레임웤입니다. 

AOP(Aspected Oriented Programming) 란  관점 지향 프로그래밍이라고 해석되는데요, 
이는, 프로젝트를 진행할때,  개발자가 고민해야하는 비지니스 로직을 핵심관심사라 보고, 그외의 인증/권한/예외처리/로깅/트랜젝션관리 등에 대한 것을 횡단관심사로 보아, 관심의 분리를 일컷습니다. 
이는, 개발자는 핵심관심사에 치중하며, 횡단관심사는 프레임웤의 각 컨테이너가 제공을 해주게 됩니다. 
그리고 각 컨테이너는 IOC(Inversion Of Control) 형태로 구성되어있는데요,  
기존에 개발방법론에서는 작성되어있는 프레임웤은 Library로서의 기능이 강했습니다. 
개발자는  비지니스 로직에 집중하면서,  횡단 관심사에 대한 호출이 필요한 경우에는 작성되어있는 프레잌웤 라이브러리를 호출해서 사용하였었지요. 
그러나, IOC 형태로 구성된 컨테이너 들은  프레잌웤 코드가 전체 어플리케이션의 처리흐름을 제어하며, 특정한 이벤트가 발생할 시마다 다형성을 통해, 어플리케이션이 확장한 메소드를 호출함으로서, 결과적으로는 제어가 프레임웤에서 어플리케이션으로 거꾸로 흐르게 되는 방법을 말합니다. 
그리고 객체가 참조하고 있는 다른 객체를 스스로가 new로 create하지 않고, 인터페이스를 통해서 Assing받아 사용하는 방식을 따르고 있습니다.

[예제1]  
App.config 
    <objects xmlns="http://www.springframework.net" >
       <object id="MyHello" type="DI.Hello, DI"></object>
    </objects>

Interface 
    interface IHello
    {
        string sayHello(string str); 
    }

Class 
    class Hello : IHello
    {
        public string sayHello(string str)
        {
            return str; 
        }
    }

MainApp
        static void Main(string[] args)
        {
            IApplicationContext ctx = ContextRegistry.GetContext();  //app.config에 설정된 object를 가져옵니다. 
            IHello hello = (IHello) ctx.GetObject("MyHello"); //  MyHello object를 노출된 interface 를 통한 Assign 
            string str = "안녕";
            string result = hello.sayHello(str);  
            Console.WriteLine(result);
        }

MainApp에서 Hello 클래스의 객체를 직접 create하지 않고, IHello 인터페이스를 도입함으로서, MainApp와 Hello와의 종속성이 제거되었습니다.  여기서 Hello가 컴퍼넌트 역할을 하게됩니다.
configuration에 사용하고자 하는 컴퍼넌트를 명시하고,  MainApp에서는  해당 컴퍼넌트를 사용할수 있도록 interface를  제공한 것입니다. 
위와 같은 프로그래밍 모델을  IOC, DI 라고 부릅니다. 


Spring.NET에서는 AutoProxy기능이 지원되는데요,  이는 특정 메소드가 호출될때, configuration에 define된 룰에 따라, 메소드호출을 intercept하여, 흐름의 제어를 할수 있게 되는것입니다. 

[예제2]
 
 
Configuration
<!--AutoProxy 설정-->
      <object id="MyServiceCommand" type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop">
        <property name="ObjectNames">
          <list>
            <value>K*</value>
          </list>
        </property>
        <property name="InterceptorNames">
          <list>
            <value>Interceptor</value>
          </list>
        </property>
      </object>
  <!-- Intercept시 호출된 클래스정보-->
  <object id="Interceptor" type="ConsoleApplication2.Interceptor, ConsoleApplication2"/>
  
 <!--Object-->
      <object id="English" type="ConsoleApplication2.HelloWorldSpeaker, ConsoleApplication2">
        <property name="Language" value="English"/>
      </object>
     <object id="Korean" type="ConsoleApplication2.HelloWorldSpeaker, ConsoleApplication2">
        <property name="Language" value="Korean"/>
      </object>
  
interface
    public interface IHelloWorldSpeaker
    {
        void SayHello();
    }

Class 
   public class HelloWorldSpeaker : IHelloWorldSpeaker
    {
       public void SayHello()
        {
            switch (language)
            {
                case Language.English:
                    Console.WriteLine("영어");
                    break;
                case Language.Korean:
                    Console.WriteLine("한국어");
                    break;
            }
        }
    }

Interceptor 
 public class Interceptor : IMethodInterceptor
    {
        public object Invoke(IMethodInvocation invocation)
        {
            Console.WriteLine("실행전");
            object rval = invocation.Proceed();
            Console.WriteLine("실행후");
            return rval;
        }
    }

또한 before/After/Around 등의 Advice를  configuration에 세팅하게되면, 메소드의 실행전후에 특정 흐름을 끼워넣을수도 있게 됩니다. 

Spring.NET에서는 Quart.NET을 이용한  스케줄러 구현을 지원합니다.일반적으로, 기존에 우리 스케줄러를 작성하기 위해서는 쓰레드개념을 생각 안할 수가 없는데요, 
이때, Threadpool을 관리함에 있어서 여러가지 고민해야될것들이 많았습니다 
Pool의 count , 객체 소멸시점, 특정 시간에만 동작하기 위한 Timer .. 외에도 여러가지 존재할것 같습니다. 
그렇다면, Spring.NET에서는 이 모든것들에 대해서 어떻게 구현하게 될까요.. 
이제부터 직접 스케줄러를 구현해 보도록 하겠습니다. 

1. configuration  
2. scheduler
3. trigger 
4. jobDetail 

configration을 작성해야 하는데요, 이는 app.config에 작성할 수도 있고, 따로 xml파일로 뺼수도 있습니다. 
configuration에는 스케줄에 해당하는 object와, 스케줄에 대한 반복적인 주기를 뜻하는 트리거, 그리고 마지막으로 각 트리거가 수행하는 Job에 대해서 명시해야합니다. 

[예제3]
 
Scheduler
<object id="quartzSchedulerFactory"  type="Spring.Scheduling.Quartz.SchedulerFactoryObject, Spring.Scheduling.Quartz">
    <property name="SchedulerName" value="quartz1"/>
    <property name="triggers">
      <list>
        <ref object="CronTrigger" />
        <ref object="SimpleTrigger" />
       </list>
    </property>
  </object>

Trigger  
<object id="SimpleTrigger"  type="Spring.Scheduling.Quartz.SimpleTriggerObject, Spring.Scheduling.Quartz">
    <!-- see the example of method invoking job above -->
    <property name="JobDetail" ref="SchedulerJob" />
    <!-- 10 seconds -->
    <property name="StartDelay" value="10s" />
    <!-- repeat every 10 seconds -->
    <property name="RepeatInterval" value="10s" />
  </object>
  <object id="CronTrigger" type="Spring.Scheduling.Quartz.CronTriggerObject, Spring.Scheduling.Quartz">
    <property name="JobDetail" ref="SchedulerJob" />
    <!-- 5초마다의 interval Fire -->
    <property name="CronExpressionString" value="0/5 * * * * ?" />
  </object>

Job
<object name="SchedulerJob" type="Spring.Scheduling.Quartz.JobDetailObject, Spring.Scheduling.Quartz">
    <property name="JobType" value="Publisher.SchedulerJob, Publisher" />
    <property name="JobDataAsMap">
      <dictionary>
        <entry key="Timeout" value="5" />
       </dictionary>
    </property>
  </object>

모든 object는 Id(Name)와 Type을 지정해주어야합니다. 
그리고, 각 오브젝트마다 가지는 프로퍼티가 조금씩 다른데요, 
스케줄에서는 해당 스케줄에 대한 반복적인 주기를 뜻하는 트리거를 지정하게됩니다. 
저는 simpleTrigger와 cronTrigger라는 두개의 트리거를 지정했는데요,  몇분에 한번씩. 처럼 간단한 작업주기인경우에는 simpleTrigger를, 일중일 중에서 토/일을 제외한 매일 아침 10시부터 12시까지 20분간격으로. 라는 조금은 복잡해보이는 반복주기인경우에는 crontrigger를 사용하면 됩니다. 
그리고 각 트리거에서는 수행할  Job에 대해서 명시를 해야하는데요, 
JobType이라는 프로퍼티를 통해, 수행할 Task의 Type을 지정하게됩니다 Type은 어셈블리명, 네이스페이스명으로 지정하시면 됩니다.
위의 configration는 Publisher.SchedulerJob을 하나는 10초마다, 하나는 5초마다 반복 수행하는 스케줄러임을 알수 있게됩니다. 
config세팅이 끝나면, 이제 Publisher.SchedulerJob을 작성해 보겠습니다. 

[예제4]
 class SchedulerJob : QuartzJobObject
    {
        protected override void ExecuteInternal(JobExecutionContext context)
        {
                 Console.WriteLine("Excute..."); 
         }
    }


SchedulerJob은 QuartzJobObject를  상속받아, 예약되어있는 ExecuteInternal메소드를 오버라이딩 하면 됩니다 
파라메터인 JobExecutionContext타입의 context에는 configration에서 작성한 해당 Job의 정보를 모두 알 수 있습니다. 
위와 같이 QuartzJobObject를 상속하여, Job을 수행하는 방식 외에, 직접 TargetMethod를 지정할 수도 있습니다.

스케줄 트리Listener를 등록해 놓으면, 트리거가 Fire될때, 혹은 misFire되거나 실행이 완료되었을때의 이벤트를 Listen할 수가 있습니다.

[예제5]
   
 public class TriggerListener : ITriggerListener
    {
        
public void TriggerFired(Trigger trigger, JobExecutionContext context)
        {
            Console.WriteLine("TriggerFired");
        }

         public void TriggerMisfired(Trigger trigger)
        {
            Console.WriteLine("TriggerMisfired");
        }

        public void TriggerComplete(Trigger trigger, JobExecutionContext context,
                                    SchedulerInstruction triggerInstructionCode)
        {
            Console.WriteLine("TriggerComplete");
        }
    }

작성된 스케줄러를 실행시켜보겠습니다. 
[실행결과]

5초마다 Crontrigger가, 10초마다 simpleTrigger가 수행되고 있으며, 각 이벤트가 Fire될때마다 Trigger를 Listen하고 있습니다.

지금까지 간략하게나마, Spring.NET을 이용하여 스케줄러를 만들어 보았는데요,, 
잘 동작하네요 :)  

읽어주셔서 감사합니다.   

'PP > SPRING.NET' 카테고리의 다른 글

일반 구성 설정(ASP.NET)  (0) 2012.01.13
Spring .Net 활용 가이드  (0) 2012.01.12
DI  (0) 2012.01.10