티스토리 뷰

최근 .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 에 대해서 주절주절 했는데, 이 프레임워크를 확장하여 훨씬 기가 막힌 재미있는 것은 다음 편에 계속 됩니다.

댓글
댓글쓰기 폼
공지사항
Total
2,833,299
Today
2
Yesterday
149
«   2023/02   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28
글 보관함