최근 .NET 에서도 오픈 소스 프레임워크가 상당히 대세이고, 많은 오픈 소스 프레임워크가 공개되고 있습니다. 개발자들은 선택의 폭이 굉장히 넓어졌고, 참고할 수 있는 레퍼런스의 양도 이제는 헤어릴 수 없을 정도입니다. 심지어 .NET Framework 소스 코드까지 디버그 심볼로 그 내부를 볼 수 도 있으며, 최근 .NET Framework 4.0 에 포함되는 일부 라이브러리는 아예 오픈 소스로 공개하고 있습니다.

이러한 프레임워크 홍수 속에서 어떤 프레임워크를 선택하느냐 또한 큰 고민이 아닐 수 없습니다. 예전 Pattern & Practice 스터디를 할 때 토론했던 내용 중에 '왜 돈주고 프레임워크를 쓰느냐! 오픈 소스를 써라' 라는 질문에 굉장히 좋은 비유의 답변을 들은 적이 있었습니다.

"내가 미국을 가기 위해서 조립 설명서를 보고 비행기를 조립해서 갈 수 도 있지만, 이미 만들어진 비행기를 타고 가는 방법이 있다. 선택은 자유다!"

필자는 오픈 소스 프레임워크를 반대하는 사람은 아닙니다. 저 또한 좋은 레퍼런스를 너무 감사하게 생각하고 있습니다. 대부분의 오픈 소스 프레임워크는 범용적으로 사용되기 위한 목적이기 때문에 도메인 집약적인 큰 프로젝트에서는 오픈 소스 프레임워크의 내부적인 파이프라인을 모르고서는 원활하게 쓰기가 힘이 들 수 도 있습니다. 특히 장애 발생 시 장애 추적의 범위가 훨씬 넓어지며, 문제 해결 또한 쉬운 작업은 아닐 것입니다.

어쨌든 나의 Dynamic Proxy 프레임워크 개발은 이러한 범용성이 강한 오픈 소스 프레임워크로는 도저히 불가능했습니다. 일부 검증되지 않은 오픈 소스 프레임워크와 돌아다니는 코드를 조합하여 원하는 기능을 만들자니 내 기분은 짜증이 나기 시작했습니다.

처음에는 P&P Unity Application Block 과 몇몇 오픈 소스를 사용하고자 했으나 제가 원하는 스팩 미달이었습니다. 일단 Unity Block 의 Dynamic Proxy 는 대략 아래와 같은 스팩을 제공해 줍니다.

종류

설명

비고

Interface Proxy

인터페이스를 구현한 객체의 Proxy 를 만듦

반드시 인터페이스를 구현해야 함

Virtual Method Proxy

Virtual 로 선언된 Method 의 Proxy 를 만듦

(.NET 에서는 명시적인 virtual 선언 없이는 불가능 하기 때문에 좀 불편하죠. 참고로 Java 에서는 명시적인 virtual 이 없이도 virtual 메서드로 컴파일 됩니다)

반드시 virtual 로 선언해야 함

Transparent Proxy

.NET Remoting 의 Real Proxy 를 이용하여 Proxy 를 만듦

성능이 느림

Interceptor Extension

프락시 객체에 AOP 와 같이 위빙(Weaving) 처리

  

결국 내가 하고자 하는 Dynamic Proxy + Mock 와 같은 좀 더 로우 레벨로 제어하기 힘들었습니다. 특히 Unity Application Block 에서는 IoC Container 와 함께 사용해야 하는 Extension 형태로 Dynamic Proxy 와 Interceptor 가 제공이 되기 때문에 단독적인 Proxy Framework 로는 사용하기에 적합하지 않았습니다.

   

DxEF.Proxy.Dynamic - Dynamic Proxy 프레임워크

결국 Interface 계약 기반의 Dynamic Proxy 와 Mock Object Proxy 를 생성이 가능한 프레임워크가 필요로 했습니다. 그리고 여기에 Interception 기능을 추가하여 Dynamic AOP 가 가능해졌습니다.

 

DxEF Dynamic Proxy 의 약간의 샘플을 보여드립니다. 어떤 느낌인지 감이 오셨는지요~?

[TestClass]

public class ProxyTest

{

[TestMethod]

public void TestMethod1()

{

InterfaceImplementationDynamicProxy<ILogger, Logger> proxy =

new InterfaceImplementationDynamicProxy<ILogger, Logger>();

var proxyObject = proxy.CreateProxy();

   

proxyObject.Write("A");

}

}

   

public interface ILogger

{

[SampleInterceptor]

void Write(string msg);

}

   

public class Logger

{

}

   

   

public class SampleInterceptorAttribute : InterceptorAttribute

{

public override IInterceptor CreateInterceptor()

{

return new SampleInterceptorHandler();

}

}

   

public class SampleInterceptorHandler : IInterceptor

{

#region IInterceptor 멤버

   

public InterceptorReturnMessage Invoke(InterceptorInputMessage input, InvokeRealMethod invoke)

{

Console.WriteLine("Before Action...");

   

var returnMsg = invoke(input);

   

Console.WriteLine("After Action...");

   

return returnMsg;

}

   

#endregion

}

   

이러한 Interface 계약 기반으로 C# 4.0 에서 제공하는 Duck Typing 을 Dynamic Proxy 만으로도 가능해집니다. 더 나아가 Mock Object 로 단위 테스트(Unit Test) 의 확장이 가능하고, PostSharp 과 같은 Assembly Rewrite AOP 방식으로도 활용이 가능합니다.

또한 빠른 성능을 위해 Proxy Object 는 Caching 이 되고, 특히 런타임에서 JIT 컴파일이 되지 않기 때문에 빠른 성능을 보장할 수 있습니다.

   

   

지금까지 단순히 DxEF Dynamic Proxy 에 대해서 주절주절 했는데, 이 프레임워크를 확장하여 훨씬 기가 막힌 재미있는 것은 다음 편에 계속 됩니다.

신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 태디 2010.01.13 22:13 신고 Address Modify/Delete Reply

    잘 이해는 안가지만 잠깐 테스트 해본 개인적인
    입장에서...

    Dynamic 키워드 데이터 타입이나 형변환에 있어서
    뭐라고 표현할까?... 굉장히 유연하네...

    var 키워드가 linq에 더 효과적인 듯 잘쓰면
    유용하지만 여기저기 .Net 3.5, .Net 4.0 프레임워크가
    더 보편화되면 초보개발자들이나 나같이 무식한
    개발자들은 쓰기 쉽고 편하다고 여기저기 남발하는건
    아닌지 모르겠다...

    잘쓰면 약 못쓰면 독이 되듯 말이야

    • 땡초 POWERUMC 2010.01.13 23:14 신고 Address Modify/Delete

      아마도 이해가 다른 듯 해서...
      Dynamic Proxy 는 내부적으로 Proxy 를 생성하는데..
      .NET Framework 에도 대표적인것이 Remoting Proxy 이고
      실제로 Runtime Type AOP 로 .NET 진영에서는 가장 널리 쓰기이기도 하는데,
      이 리모팅 프락시의 가장 큰 단점은 클래스 단위밖에
      Interceptor 를 걸 수 없다는 단점이 있어..
      결국 .NET Remoting Proxy 는 Nested Method Proxy 를 구현할 수 없다는 단점이 있었는데...
      이것을 극복하고자 다양한 DI Framework 나 Spring.NET 에서 구현한 방법인데
      이번 Dynamic Proxy 는 쓰임새가 명확한 프레임워크라고 볼 수 가 있어.
      좀 범용적이지는 않지만, Dynamic Proxy 와 더불어 WCF 와 통합할 목적이었거든 ^_^;;
      에구에구

    • 테디 2010.01.14 07:00 신고 Address Modify/Delete

      고마워 좀더 공부해보고 리플 달아준 부분에 대해서 접근을 해야겠네

  2. 2010.01.26 18:22 신고 Address Modify/Delete Reply

    지금은 잘 maintenance 되지 않고 있는 듯한 linfu project

    http://code.google.com/p/linfu/

    등에 비해 확실히 뛰어난 점이 있는지요?

    • 땡초 POWERUMC 2010.01.26 18:47 신고 Address Modify/Delete

      같은 Dynamic Proxy 라는 점에서 그리 뛰어난 점은 없습니다.
      대부분의 Proxy 프레임워크가 그러하듯 말입니다.

      하지만 제가 만든 Dynamic Proxy 는 위의 3가지 Proxy 이 외의 Proxy 객체를 만들 수 있습니다.
      (그리고 현재는 위의 3가지를 지원하지도 않지만, 지원하도록 할 수도 있지요.)

      예를 들어, Interface 를 통해 Mockup 을 하는데, 다음 장에 소개가 되는 Dynamic Proxy SoaService 와 연관이 깊습니다.

      어찌되었건 더 뛰어난 점도 뒷쳐지는 점도 없습니다만,
      Linfu 나 Unity 의 Interceptor/Proxy 기능도 제공되지만,
      궁극적으로 저는 ESB/SOA 를 구현하는 Proxy 를 주목적으로 하였습니다.

    • 2010.01.27 00:37 신고 Address Modify/Delete

      어디서 많이 본 프로젝트인데.. 싶어서 단 댓글에 친절하게 답변해주시니 그저 감사할 따름입니다. (굽신)

      하긴 그전에도 리모팅을 위한 serialization을 고려했다든지, 요샌 WCF 등과 연계해서 객체를 주고받는 쪽과 연계시키는게 많아보이더군요. 전문 프로그래머가 아니라 자세히는 안파봤지만..