객체지향 프로그래밍 이야기

IoC(Inversion of Contol)[1], 우리말로는 ‘역전제어’라고 한다. 객체지향 프로그래밍의 기본은 만들어진 객체를 잘 쓰는 것 부터 시작한다. 이 경우 개체(Object)를 인스턴스화(Instance)하기 위해 개체(Object)를 직접 참조해야 한다.

개체(Object)는 class 로 선언되는 빌딩의 명세서(설계도?)와 같고, 인스턴스(Instance)는 만들어진 빌딩(Building-건물)을 의미한다. 전자를 개체(Object)라고 부르며, 후자를 객체(Object) 또는 인스턴스라고 부른다.

명세서를 찍어내는 방법은 매우 간단하다. Building b = new Building() 이것이 객체지향에서 개체를 인스턴스화 하는 코드가 되겠다. 그런데 현실에서의 건물은 매우 다양하다. 아파트도 있고, 오피스텔도 있고, 고층빌딩도 있다. 어떤 건물은 지하 주차장이 완비되어 있고, 어떤 건물은 주차장이 옥상에 있다. 물론 없는 건물도 있다. 어떤 건물은 건물 전체가 주차장이다.

하나의 객체로 건물의 모든 기능을 담기란 힘들다. 방, 화장실, 출입문, 엘리베이터 등 각각 작은 객체들을 기능 단위로 쪼개야 나중에 다른 건물을 지을 때도 재사용성이 높아진다. 여러개로 쪼개진 기능을 한대 묶어 복합적으로 배치하면(Complex + Composition) 오피스텔이 되기도 하고, 원룸텔이 될 수 있다. 이 얼마나 아름다운 객체지향의 세계인가.

그런데 어느 엘리베이터 업체가 가장 최신의 기능을 넣기 위해 독자 표준으로 만들었다. 이 엘리베이터는 총 중량도 검사해서 작동 여부가 결정되고, 중량이 넘어서면 목적지 까지 중간에 서지도 않는 똑똑한 지성도 갖추었다. 환풍 설비도 갖추고, 향기도 나고, 내부 벽은 고급스러운 스테인레스로 쫙 깔았다.

공포 영화에나 나올 법한 허름한 구닥다리 병원의 삐그덕 거리는 엘리베이터와는 차원이 다르다. 이 병원 건물은 환상적인 저 엘리베이터 업체의 객체를 샀다. 젠장, 안맞는다. 크기도 국제 표준의 규격과 다르고, 외벽과 연결되는 환풍 설비는 꽉 끼어 찌그러질 판이다. 마치 38인치 바지를 입는 사람이 30인치 바지를 억지로 입으려는 것과 같다.

인터페이스 지향적인 프로그래밍 이야기

이 엘리베이터 업체는 최첨단 기술이 도입되는 건설사의 수주를 받아 개발한 엘리베이터인데, 건설사와 계약이 끝나니 손가락만 빨게 생겼다. 독자 표준의 엘리베이터를 국제 표준에 맞게 다시 만들었고 이제야 다시 매출이 조금씩 오르기 시작했다.

국제 표준 규격에 맞게 정해진 규약을 지켜서 만들었다. (말도 안되는 ISOxxxxElevatorOutputV1 이라는 인터페이스가 규약이라고 치자)

public interface IStarbucksElevator
{  
    ISOxxxxElevatorOutputV1 Open();  
    ISOxxxxElevatorOutputV1 Close();

    ISOxxxxElevatorOutputV1 Up();  
    ISOxxxxElevatorOutputV1 Down();
}  

세상이 변하고 살기 좋아지면서 새로운 기술도 쏟아진다. 국제 표준 기구는 엘리베이터에 범죄 예방을 위해 CCTV 규격을 V2 에 포함시켰고, V3 버전에는 어린이들도 쉽게 버튼을 누를 수 있도록 버튼의 위치와 비상벨의 위치가 매우 낮아졌다.

이 엘리베이터 업체는 모든 최신 규격을 지키기 힘들다. 기술력 확보를 위해 인재도 뽑아야 하고, 최신 표준 규격에 맞는 부품을 수입도 해야하고, 아직 모든 준비는 되지 않았지만, 국제 표쥰은 지킬 수 있다. 이렇게 말이다.

public interface IStarbucksElevator
{  
    ISOxxxxElevatorOutputV1 Open();  
    ISOxxxxElevatorOutputV3 Close();

    ISOxxxxElevatorOutputV1 Up();  
    ISOxxxxElevatorOutputV2 Down();
}  

그리고 국제 표준 인터페이스는 하위 호환을 지켜야 하므로 이렇게 생겨먹었다.

public interface ISOxxxxElevatorOutputV1
{  
    // ... 생략 ...
}  

public interface ISOxxxxElevatorOutputV2 : ISOxxxxElevatorOutputV1
{  
    // ... 생략 ...
}  

public interface ISOxxxxElevatorOutputV3 : ISOxxxxElevatorOutputV2
{  
    // ... 생략 ...
}  

국제 표준을 지키기 때문에 명확하게 인터페이싱이 가능하지만, 이 업체의 내부 구현 코드는 점점 엄망이 되어 간다. 내부적으로 지나치게 코드의 버전이 많아지고, 또 갈리게 된다.

이 업체는 표준 규격에 맞게 제작된 엘리베이터의 종류가 여럿 있다. 소형, 중형, 대형 건물마다 필요한 엘리베이터 버전들이 많다.

이제는 엘리베이터 내부 개발자들은 객체를 생성하는 것이 점점 무서워질 정도다. 가끔 헷갈리기도 하는데, 소형 엘리베이터의 코드에서 return new ISOxxxV1LargeBuildingInternalV2_5 이렇게 대형 건물용 엘리베이터 객체를 반환했다간 아작이 난다.

인터페이스 기반의 프로그래밍은 분명한 장점이 많다. 특히 인터페이스 기반으로 다른 객체를 쓸 때 편하다. 내부적인 코드의 개선이 필요하거나 인터페이스에 살짝 변화가 온다던가, 분석이 필요한 경우 인터페이스 기반으로 구현된 코드를 보면 난독증이 올 지경이다. 특히, 인터페이스나 객체들을 이용하여 다형성을 가지는 개체들은 디버깅 기능이 떨어지는 개발툴(IDE)에서는 거의 시간과 씨름하는 노가다와 같다.

국내의 엘리베이터 적용에 관한 법이 바뀌었다. CCTV 기능이 있는 국제 표준 버전 2(ISOxxxxElevatorOutputV2) 기능이 없으면 대형 건물에 엘리베이터를 설치할 수 없다. 또 구현해서 바꿔야 한다. return eturn new ISOxxxV1LargeBuildingInternalV2_5_RequiredCCTV

객체의 생성과 파괴는 간접적 컨테이너(Container)에 의해

그렇다. 객체를 직접 생성하려고 하면 강하게 응집력이 생긴다. 그래서 인터페이스를 활용하여 응집력을 낮추었다. 근데 매우 복잡한 객체지향적인 코드에서는 인터페이스 기반은 너무 힘들다. 인터페이스가 변하지 않음을 보장하고 인터페이스의 상속의 스택이 없거나 매우 짧다면 쉽지만, 스택이 깊어지면 당연히 더 어려워질 수 밖에 없다. 디버깅 경험을 떠올려 보라. 메서드 안의 메서드(Inner Method), 또 그 안에서 또 다른 메서드 호출이 깊어지면 복잡해질 수 밖에 없다.

그래서 IoC(Inversion of Control-역전 제어)는 직접 개체를 핸들링 하던 것을 간접 참조를 통해 제어 방향을 완전히 반대로 바꾸는 방법이다.

기존의 객체를 직접 핸들링 하던 방식과 인터페이스 기반의 방식을 표현하면 아래와 같이 표현할 수 있겠다.


아래의 그림은 각각의 장점과 단점을 기술한 표이다.

IoC(Inversion of Control)에 대해 필자와 같은 돌팔이가 아닌 ‘집단 지성’의 명쾌하고 깔끔한 정의는 링크를 통해 확인하기 바란다.


Umc Core IoC 통합 컨테이너의 탄생 배경

Umc Core IoC는 여러 개의 서로 다른 프레임워크의 인터페이스와 스키마, 그리고 Dependency & Injection, AOP Weaving 의 인터페이스를 모두 통합한 프레임워크이다.

오픈 소스의 시대이다. 객체를 다루는 트랜드도 바뀌어 이 전에 아티클의 내용인 다이나믹 프록시(Dynamic Proxy) 와 AOP(Aspect Oriented Programming) 등과 같은 기법들을 사용한다.


아래 현재 버전의 오픈 소스가 참조하는 IoC 컨테이너 오픈 소스는 2011년 당시와 다를 수 있음.


문제는 오픈 소스들마다 사용하는 다이나믹 프록시 오픈 소스, IoC 컨테이너 오픈 소스가 제각기 다르다는 문제에서 출발하게 된다. NHibernate, iBatis.NET(현 myBatis.NET)Castle Windsor 프레임워크의 다이나믹 프록시 및 IoC 컨테이너를 사용하고, Enterprise LibraryUnity Application Block 프레임워크를 사용한다.

만약, Enterprise Library를 기반으로 ORM 프레임워크로 NHibernate 조합으로 사용한다고 치자. 내부적으로 객체를 생성하는 곳이 두 군데가 된다. 이 객체의 생명 주기를 관리하는 곳도 두 곳이 된다. 다이나믹 프록시(Dynamic Proxy) 개체가 생성된다면 똑 같은 개체가 두 군데에서 생성하므로 괜한 메모리 공간만 차지하게 된다.

아래의 그림은 2011년 당시 수집한 자료를 기반으로 작성이 되었다.



하나의 응용 프로그램의 레이어(Layer) 안에서 두 개의 컨테이너와 프록시 객체가 생성되는 것도 문제지만, 두 개의 프레임워크가 제공하는 인터페이스도 판이하게 다르다는 것은 코딩 스타일에 문제가 된다. 당연히 응용 프로그램 차원에서는 더 큰 문제로 보아야 된다.

아래의 그림에선 두 개의 IoC 프레임워크가 전혀 다른 XML 스키마와 인터페이스를 제공하는 것을 알 수 있다.



Umc Core IoC 프레임워크의 소스 코드는 https://github.com/powerumc/UmcCore/tree/master/Src/Base%20Frameworks/Src/Core/IoC 에서 먼저 확인할 수 있다.

To be continue #2…


  1. In software engineering, inversion of control (IoC) is a programming technique, expressed here in terms of object-oriented programming, in which object coupling is bound at run time by an assembler object and is typically not known at compile time using static analysis.  ↩

    http://en.wikipedia.org/wiki/Inversion_of_control


'Umc Projects > Umc.Core' 카테고리의 다른 글

Umc Core IoC 통합 컨테이너 #1  (0) 2013.05.24
Umc.Core 프레임워크 다이나믹 프록시(Dynamic Proxy) #1  (0) 2013.05.23
Umc.Core 미공개 Preview  (6) 2008.05.14
Umc.Core 란?  (0) 2007.12.01
Posted by 땡초 POWERUMC

댓글을 달아 주세요

요즘 참 할일도 많은데 할 수 있는 일이 점점 줄어든다. 필자는 블로그 버킷 리스트(bucket list)를 작성하는데 블로그가 사망하기 전에 꼭 해야 할 일을 목록으로 만들어 놓고 하나 하나씩 글을 써 나간다. 근데 할 일이 늘어만 간다. ㅠ

  • 당장 쓸 수 있는 글 39개
    사소한 개발 기술부터 심도있는 내용으로 흐리멍텅한 개념을 글을 쓰면서 잡아 나가는 것들

  • 개발 후 산출물로 쓸 글 37개
    오픈소스로 내놓을 계획, 또는 알고 있는 것들에 대한 증명이 필요하고 그 후에 쓸 수 있는 글

  • 연구개발 11개
    배우고 싶은 것, 하고 싶은 것, 해야 하는 것들이고 공부해야 쓸 수 있는 글들

아무튼 점점 쓸 것들이 늘어만 가지만, 하나 하나 하다보면 쓸게 없어 지는 날이 올거라 믿는다 >.,<

#1 - Umc.Core 프레임워크 다이나믹 프록시(Dynamic Proxy)

다이나믹 프록시(Dynamic Proxy)는 최근 IoC(Inversion of Controls)라는 개념으로 확장되고 객체지향 프로그래밍(OOP)의 효율성을 극대화한다. 다이나믹 프록시 기법은 이미 오래 전부터 존재해 왔다.

C++의 스마트 포인터(Smart Pointer) 처럼 직접 포인터를 건들이지 않고 레퍼런스 카운팅이나 객체의 생명주기를 프록시 개체(Proxy Object)를 통해 관리하는 기법이 있고, RPC(Remote Procedure Call)과 같은 원격 프로시저 호출을 위해 프록시 패턴(Proxy Pattern)이 기반에 깔려 직접 원격 구현을 숨기고 간단한 인터페이스만 제공해 주는 패턴 등 매우 다양하다.

최근의 다이나믹 프록시(Dynamic Proxy)는 IoC(Inversion of Control), DI(Dependency Injection), ORM(Object Relation Mapping), AOP(Aspect Oriented Programming) 등 객체를 다루는 프레임워크에서 기본적으로 채용할 만큼 객체를 다룸에 있어 가장 기본적인 기법 또는 기술에 속한다.

필자가 오늘 다루어 볼 내용은 이런 프록시 패턴(Proxy Pattern)이 기반이 되는 개체 제어를 위한 기법이다.

먼저 다이나믹 프록시(Dynamic Proxy)에 대해 예전에 잠깐 쓴 글을 참고하자.

과거 2009년도 닷넷엑스퍼트 재직 시절에 다이나믹 프록시(Dynamic Proxy)를 만들었다가, 2011년 좀 더 나은 객체 디자인으로 완전히 다시 만든 다이나믹 프록시(Dynamic Proxy) 프레임워크가 지금 설명할 Umc.Core.Dynamic.Proxy 이다.

Umc Core 프레임워크는 오픈 소스로 공개되어 있으며 누구든지 소스 코드를 열람할 수 있다. 현재 소스 코드는 다음의 링크를 통해 제공된다.

그 외에 필자가 공개한 소스 코드도 여럿 있으니 관심있는 분들은 참고하기 바란다.

 

 







#2 - 코드부터 보자.

만약 관리 언어(Managed Language)의 동작 매커니즘을 이해하지 못했다면 마치 마법과도 같은 기법으로 보일 것이다. 아래의 코드는 완벽하게 돌아가는 소스 코드이다.

using System;  
using Umc.Core.Dynamic;  

namespace ConsoleApplication1
{  
public interface IPerson
{
    string Name { get; set; }
    string Email { get; set; }
}  

class Program
{
    static void Main(string[] args)
    {
        var type   = DynamicProxyObject.InterfaceImplementationType<IPerson>();
        var person = (IPerson)Activator.CreateInstance(type);

        person.Name  = "POWERUMC";
        person.Email = "powerumc at 지멜";

        Console.WriteLine("Name : {0}, Email : {1}", person.Name, person.Email);
    }
}
}  

한번 위의 코드를 보자. IPerson 인터페이스는 IPerson을 구현하는 클래스가 반드시 있어야 객체를 생성할 수 있다. 다음과 같이 말이다.

public class Person : IPerson
{
    public string Name { get; set; }
    public string Email { get; set; }
}   

C#의 상식으로 보아도 인터페이스(Interface)는 인스턴스를 생성할 수 없으며, 인스턴스를 생성하기 위해 구현 클래스가 반드시 존재햐여 하는 것 쯤은 알고 있을 것이다. 즉, Person 클래스가 있어야 IPerson person = new Person(); 으로 객체를 생성할 수 있다. 분명, 처음 코드의 DynamicProxyObject.InterfaceImplementationType<IPerson>(); 가 뭔가의 마법을 부리는 것이 확실하다고 보면 된다.

#3 - 다이나믹 프록시(Dynamic Proxy) 의 다른 구현 방법들

방금 언급한 DynamicProxyObject.InterfaceImplementationType<IPerson>(); 코드가 바로 class 로 구현조차 되지 않은 클래스를 동적(Dynamic)으로 런타임에 생성한다. 이 동적 클래스를 런타임에 생성하기 가장 쉬운 방법이 있는데, 그것은 .NET Framework에서 제공하는 CodeDomProvider 이다.

간단히 CodeDomProvider를 언급만 하고 넘어가보자. CodeDomProvider는 C#, VB.NET의 객체 표현을 Code Dom으로 표현할 수 있는데, 각각 CSharp, VB.NET Provider를 제공해 주고, 런타임에 컴파일을 한다. 다만, 컴파일 시간이 동적 객체 생성 기법 중에 가장 느리다.

그리고 C# 3.0부터 지원하는 람다 표현식(Lambda Expression)을 이용하는 방법이다. 이 람다 표현식도 내부적으로 CodeDom과 매우 유사하다. 단점이라면, 객체의 이름(Class Name)과 주소(Namespace) 등을 원하는데로 줄 수 없다. LambdaExpression 클래스의 맴버들이 많은데, 이것들로 모든 구현이 가능하다. 간단한 예제 코드를 보자.

Expression<Func<string, string>> expression = (s) => "Hello " + s;               
var func = expression.Compile();               
var ret = func("POWERUMC");   
Console.WriteLine(ret);

이 코드를 실행하면 “Hello POWERUMC” 라는 결과가 나오는 것을 확인할 수 있다.

이렇게 알게 모르게 이미 .NET Framework에서 다이나믹 프록시(Dynamic Proxy) 기법을 쓰는 곳이 의외로 많다. C# 컴파일러는 익명의 표현식들을 내부적으로 컴파일하면서 메서드로 만들어 버리기도 한다. 이렇게 똑똑한 컴파일러 덕분에 람다 표현식이나 LINQ의 성능이 매우 좋다는 것이다.

이 외에 동적메서드(DynamicMethod) 방법이 있는데, 얘는 그냥 넘어가도 무관하다.

#4 - 다이나믹 프록시(Dynamic Proxy) 개체가 생성되는 일련의 순서

동적 개체가 만들어지려면 어떤 순서가 필요할까?

먼저 객체지향 언어라는 점을 생각해볼때, 객체의 주소(Namespace)와 이름(Type Name)이 필요하다. 필자의 프레임워크 코드 중 Umc.Core.Dynamic.Proxy.Builder 네임스페이스의 ModuleBuilderExtension와 TypeBuilderExtension이 그 역할을 한다.

Type을 생성하기 위해서는 생성자 하나 이상이 반드시 필요한데, Object를 상속하는 타입을 만들어야 한다. 아시다시피 public class Person 클래스는 암묵적으로 public class Person : Object 를 상속하게 된다. 그래서 타입을 생성하고 하나의 생성자를 만들고 나면, 부모 객체인 Object의 생성자(Constructor)를 호출을 해주어야 한다. 당연히 부모가 있어야 자식이 있는 것과 같다.

이 때 반드시 주의해야 하는 것이 있다. 생성자는 인스턴스를 생성하는 생성자가 있고, static 생성자가 있다. 만약 static 생성자인 경우는 부모 객체인 Object 생성자(Constructor)를 호출하면 안된다.

Object 생성자를 타입의 생성자 안에서 호출하려면 다음과 같은 코드를 이용하면 된다.

il.Emit(OpCodes.Ldarg_0);  
l.Emit(OpCodes.Call, typeof(object).GetConstructors([0\]);  

이제 IPerson의 프로퍼티(Property)를 구현한다.

IPerson의 프로퍼티 목록은 리플랙션(Reflection)을 이용하여 쉽게 얻어낼 수 있다. 간단히 typeof(IPerson).GetProperties(); 면 된다. (프레임워크 내부에선 더 복잡할 수 있음)

C#의 프로퍼티는 컴파일을 하게 되면 프로퍼티가 메서드로 치환된다. 예를 들어, public string Name { get; set; } 코드는 다음 처럼 컴파일러가 치환한다.

public string get_Name() { ... }  
public void set_Name(string name) { ... }  

그러므로, 다이나믹 프록시를 구현할 때도 프로퍼티를 선언해 준 후에 get, set 메서드를 구현해 주어야 한다. 이를 Umc.Core에서 다음고 같이 구현하였다.

public ICodeLambda Get()
{  
var type       = new TypeBuilderExtension(null, this.TypeLambda.TypeBuilder);  
var methodAttr = this.TypeLambda.MethodAccessor.MethodAttribute | MethodAttributes.NewSlot | MethodAttributes.Final | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig;  
var method     = type.CreateMethod(methodAttr, propertyBuilder.PropertyType, String.Concat("get_", propertyBuilder.Name), Type.EmptyTypes, null, false);  

propertyBuilder.SetGetMethod(method);  

return new CodeLambda(this.TypeLambda, method.GetILGenerator());
}  

public ICodeLambda Set()
{  
var type = new TypeBuilderExtension(null, this.TypeLambda.TypeBuilder);  

var methodAttr = this.TypeLambda.MethodAccessor.MethodAttribute | MethodAttributes.NewSlot | MethodAttributes.Final | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig;  
var method     = type.CreateMethod(methodAttr, typeof(void), String.Concat("set_", propertyBuilder.Name), new Type[] { propertyBuilder.PropertyType }, null, false);  
method.DefineParameter(1, ParameterAttributes.HasDefault, "value");  

propertyBuilder.SetSetMethod(method);  

return new CodeLambda(this.TypeLambda, method.GetILGenerator());

}  

그리고 get, set 메서드의 내부 코드는 다음과 같이 구현된다.

public ITypeLambda GetSet()
{  
this.TypeLambda.FieldAccessor.FieldAttribute = FieldAttributes.Private;  
var field = this.TypeLambda.Field(this.propertyBuilder.PropertyType, String.Concat("__", propertyBuilder.Name));  

var get = this.Get();
{
    get.Return(field);
}  

var set = this.Set();
{
    set.IL.Emit(OpCodes.Ldarg_0);
    set.IL.Emit(OpCodes.Ldarg_1);
    set.IL.Emit(OpCodes.Stfld, ( (IValuable<FieldBuilder>)field ).Value);

    set.Return();
}  

return this.TypeLambda;
}  

위의 코드가 그 흔한 프로퍼티의 구현부인 public string Name { get { return this._name; } set { this._name = value; } } 를 구현하는 코드가 되겠다. 별거 아닌 코드지만 내부적으로 프로퍼티와 메서드를 생성하고, 그 구현 코드를 IL 코드로 재구현 하면 역시 조금 난이도가 높아진다.

메모리에서 개체 포인터의 엑세스를 방지하기 완료 방법

지금까지는 메모리에 동적인 코드들을 IL 코드들로 구현하였다. 모든 구현이 완료되었으면 더 이상 메모리에서 IL 코드가 위변조 되거나 .NET 코드 정책에 위배되지 않도록 엑세스 접근을 막아야 한다.

이 코드는 Umc.Core.Dynamic.Proxy.Lambda.TypeLambda 클래스의 CreateType() 메서드가 완료시킨다. 이 코드는 다음과 같이 구현 되었다.

public Type ReleaseType()
{  
if (this.TypeBuilder == null)
{
    throw new NullReferenceException(this.TypeBuilder.GetType().Name);
}  

return this.TypeBuilder.CreateType();
}   

코드 구현의 완료를 알렸다면 이제 동적 타입(Dynamic Type) 개체가 완성이 된다. 즉, 맨 처럼 IPerson 인터페이스를 구현하는 동적 개체(Dynamic Object)인 Person 개체의 타입이 되는 것이다. 즉, 이 Person 개체는 런타임에서 메모리상에 만들어진 것이 되겠다.

이리하여 Activator.CreateInstance(type) 으로 메모리상에 만들어진 Person 클래스를 생성할 수 있게 되는 것이다.

다이나믹 프록시(Dynamic Proxy) 개체의 모습

메모리상에서 만들어진 Person 개체의 타입은 내부적으로 규칙을 정해서 만들었다. Person 객체를 생성하여 이 객체의 타입을 보면 괴상한 이름으로 지어졌다.

var type   = DynamicProxyObject.InterfaceImplementationType<IPerson>();  
var person = (IPerson)Activator.CreateInstance(type);  

// 결과 -> dynamic_46c8ecaab09b41cbaa814511f69f1974

이 타입이 속한 주소(Namespace)와 모듈(Module)을 직접 디스크에 저장할 수도 있는데, 이런 방법을 이용하여 코드 난독화(Code Obfuscation) 처럼 사용할 수도 있다.

또 다이나믹 프록시(Dynamic Proxy)를 활용해 중간에 로깅(Logging)을 하거나 트랜잭션(Transaction) 처리를 할 수 있는 AOP 를 구현할 수도 있는 것이다. (AOP 구현 기법 중 하나이며, 다른 방법이 더 있다.)

또, 사용 편의성을 위해 고안된 것이 체이닝(Chaining) 방법을 이용하여 런타임 코드를 더 쉽게 만드는 방법을 Umc Core 프레임워크에서 제공한다. 다음의 코드를 보면 쉽게 이해가 될 것이다.

using System;  
using System.Linq;  
using System.Reflection;  
using Umc.Core.Dynamic.Proxy.Lambda;  

namespace ConsoleApplication1
{  
internal class Program
{
    private static void Main(string[] args)
    {
        string typeName = Guid.NewGuid().ToString("N");
        string methodName = Guid.NewGuid().ToString("N");

        var assembly = new AssemblyLambda().Assembly();
        {
            var module = assembly.Module();
            {
                var type = module.Public.Class(typeName);
                {
                    var constructor1 = type.Public.Constructor();
                    {
                        constructor1.Emit.EmitWriteLine("This is constructor");
                        constructor1.Return();
                    }

                    var constructor2 = type.Private.Static.Constructor();
                    {
                        constructor2.Emit.EmitWriteLine("This is (private static) constructor");
                        constructor2.Return();
                    }

                    var method = type.Public.Static.Method(methodName);
                    {
                        method.Emit.EmitWriteLine("This is emitted writeline");
                        method.Return();
                    }
                }

                var releaseType = type.ReleaseType();
                var obj = System.Activator.CreateInstance(releaseType);
                var releaseMethod = releaseType.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static);

                Console.WriteLine("Release type is {0}", releaseType.AssemblyQualifiedName);
                Console.WriteLine("Release method is {0}", releaseMethod.Name);

                releaseType.GetMethod(methodName).Invoke(null, null);

                Console.WriteLine("".PadLeft(50, '-'));

                releaseType.GetMethods().ToList().ForEach(m => Console.WriteLine("Method Name is " + m.Name));
            }
        }
    }
}
}



// 결과 ->  
This is (private static) constructor  
This is constructor  
Release type is bdfd27e5e7ed446d8702fe172733d937, 4a8f6dd24e1f4054b551cca95ad0870b, Version=0.0.0.0, Culture=neutral,  PublicKeyToken=null  
Release method is 389b4a43a1ba4dc1b1391b5b06633645  
This is emitted writeline  
Method Name is 389b4a43a1ba4dc1b1391b5b06633645  
Method Name is ToString  
Method Name is Equals  
Method Name is GetHashCode  
Method Name is GetType  

위의 코드와 같이 좀 더 직관적으로 동적 코드를 만드는 방법을 Umc Core에서는 제공해 주고 있다.

재미있는 것은 메서드의 이름이다. 결과 출력 중 Method Name is 389b4a43a1ba4dc1b1391b5b06633645 이 있는데, 놀랍게도 메서드의 이름이 숫자로 시작한다. C# 언어 사양 중 변수의 타입, 변수 등의 이름은 반드시 알파벳 문자로 시작해야 함에도 불구하고, 숫자로 시작하다니…

이는 C#의 언어 사양과 CIL(Common Intermediate Language) 언어의 사양이 다르기 때문이다. 심지어 숫자가 아닌 특수문자로 시작해도 된다. 앞서 말했다시피 이런 방법을 이용하여 코드 난독화(Code Obfuscation) 가 가능하다.

비록 대부분의 Umc Core 소스 코드를 공개하지 않았지만, 미공개 코드 중 코드 난독화 툴도 함께 포함이 되어있고, Junk Assembly를 만드는 툴, AOP based Compile 툴 등도 포함이 되어있다. ㅎㅎㅎ; 아쉽지만 여전히 미공개 분은 공개하지 않을 예정이다. 더불어, 관심있는 독자라면 CIL 언어 스팩의 사양을 살펴보는 것도 좋을 것이다.

결론

지금까지 살펴본 다이나믹 프록시(Dynamic Proxy)를 살펴보았다. 이 기법은 IoC, DI, AOP, ORM 등 최신 객체 제어 기술들의 가장 근간이 되는 기법이다. 여러분들이 최신 기술들로 IoC, DI, AOP 등을 구현하고 싶다면 당장 오픈소스를 이용하면 될 것이다.

아마 필자처럼 .NET 기반으로 다이나믹 프록시(Dynamic Proxy)를 직접 구현해서 쓰는 것은 매우 드문 일이다. 이미 검증된 오픈 소스들도 많기 때문에 굳이 이를 구현해서 쓸 필요는 없다.

하지만 이런 오픈 소스를 이용하여 쓰는 것은 그리 어렵지 않겠지만, 이런 오픈 소스를 이용하여 어떻게 코드를 만드느냐는 성능이나 내부적으로 동작하는 효율성에 영향을 미칠 수 있다. 즉, 자신이 오픈 소스를 이용하여 만든 코드가 효율적인 코드, 그리고 메모리상에서 Clean Code로 동작하느냐는 별개의 문제이다.

필자와 같이 다이나믹 프록시(Dynamic Proxy)를 구현해 보았다면 여러분들이 얼마나 위험한 코드를 많이 만드는지 알 수 있다. 즉, 오픈 소스를 써보기만 했다면 절대로 알 수 없는 고급 기술이다.

ASP.NET MVC 등과 같은 프레임워크에 IoC 등이 통합되면서 내부적으로 이와 유사한 방법을 쓴다. 특히 웹 개발에 있어 IoC와 같은 프레임워크는 굉장히 위험할 수 있다. 설명하자면 지금까지 쓴 내용보다 더 복잡하고 많은 내용으로 설명이 필요할지도 모른다.

만약 관리 언어(Managed Language) 등으로 만들어진(자바도 구현 기법이 유사함) 응용 프로그램의 고성능 튜닝, 트러블 슈팅, .NET 플랫폼에 관심이 많은 독자라면 반드시 이해하고 넘어가야 할 내용들이다. 그리고 오픈 소스를 이용하여 다이나믹 프록시(Dynamic Proxy)를 간접적으로 사용만 한다면 가볍게 읽고 넘어가도 좋다. 소소한 개발 일상의 이야깃 거리도 될 것이다.


필자는 이 외에도 다이나믹 프록시(Dynamic Proxy)를 바탕으로 이를 IoC와 통합하고 AOP, ORM 등을 구현하는 방법도 알아볼 것이다. Umc Core는 오픈 소스로 공개되어 있으며 위키 페이지를 만들겸 하나씩 정리하고자 한다. 

'Umc Projects > Umc.Core' 카테고리의 다른 글

Umc Core IoC 통합 컨테이너 #1  (0) 2013.05.24
Umc.Core 프레임워크 다이나믹 프록시(Dynamic Proxy) #1  (0) 2013.05.23
Umc.Core 미공개 Preview  (6) 2008.05.14
Umc.Core 란?  (0) 2007.12.01
Posted by 땡초 POWERUMC

댓글을 달아 주세요

윈도우 8, 요즘 인기가 많다. 일반 사용자들의 후기도 많이 보이고, 더불어 개발자들에게도 기존의 개발 경험을 살려 그래도 개발이 가능해서 인기가 많다. 더불어 C++/CX와 HTML5로 개발이 가능하다.

   

WinRT와 WinMD

그 중에서 C#/XAML을 이용하여 앱을 개발할 경우 Windows 8 Runtime(WinRT)의 라이브러리를 이용하여 개발하게 되는데, 마이크로소프트에서는 이 WinRT를 관리 언어가(Managed 플랫폼 환경) 아닌 C++로 만들어진 네이티브(Native)로 컴파일 되어 있다. 확장된 COM 기반이기 때문에 C#과 HTML5에서 모두 이 라이브러리 APIs 집합을 사용할 수 있다. 이것은 매우 큰 장점이 분명하다.

그런데 말이다. 이 WinRT 자체가 매우 성급하게 만들어진 라이브러리라는 것이 여럿 보인다. 그 중 네이티브로 컴파일된 환경에서 C#과 유사하게 런타임상의 객체나 타입 정보를 알아내기 위해 RTTI(RunTime Type Identification)을 C++/CX 컴파일 시에 자동으로 구현이 된다. 그리고 RTTI를 위해 사용되는 WinRT의 API 정보의 일부는 .WinMD 파일로 저장이 된다. 이를 윈도우 런타임 라이브러리(Windows Runtime Library)라고 하며, 이 라이브러리는 윈도우 8 앱을 개발하는 환경 모두에서 사용할 수 있다.

   

   

   

   

윈도우8 WinRT, XAML의 미완성을 의미하는 IXamlMetadataProvider와 IXamlType 인터페이스

여기에서 문제가 발생한다. 모든 객체들은 C++/CX과 C#에서 XAML(eXtensible Application Markup Language)에서 다룰 수 있다. 그리고 Windows.UI.Xaml 네임스페이스에 XAML과 관련된 APIs 집합이 있다. 그런데 WinRT는 XAML을 핸들링 할 수 있는 라이브러리를 완벽하게 구현해 놓지 못했다.

그래서 WinRT의 IXamlMetadataProviderIXamlType 인터페이스가 생겼다. 이 인터페이스가 WinRT가 XAML을 (꽁수로) 핸들링하기 위해 만들어진 인터페이스로 보인다.

코드에서 새로운 객체를 생성해서 사용하고 싶으면 var obj = new LoginView(); 와 같이 새로운 객체를 생성하는 new 키워드를 사용하면 된다.

객체지향을 완벽하게 표현하는 XAML에서도 마찬가지다. XAML에서 다음처럼 LoginView 객체를 생성할 수 있다.

   

   

여기에서 IXamlMetadataProvider가 미완성 XAML임을 증명해 준다. 윈도우8 모던 앱(Modern App)에서 XAML에서 객체가 생성되는 경우 컴파일 시에 자동으로 생성되는 XamlMetadataProvider.g.cs 파일에서 객체를 생성해 준다. (g는 Generated를 의미한다). 자동으로 생성되는 이 코드는 다음과 같은 코드가 포함이 되어있다.   

   

XAML에서 LoginView 객체 생성을 요청할 경우 IXamlMetadataProvider를 구현한 코드를 통해 객체를 대신 생성한다. 다시 말해, 하드 코딩이 되어있다.   

이는 매우 유감이다. 이는 즉, 런타임상에 동적으로 생성되는 객체나 앱 컴파일 시에 해당 클래스가 포함이 되어 있지 않다면, XAML은 객체를 생성하지 못하게 된다. 동적인 무언가에 의해 생성되는 객체는 XAML에서 명시적으로 객체를 생성할 수 있는 방법이 없어진 것이다. (단, 명시적인 호출)

   

   

사용자가 구현하는 IXamlMetadataProvider

일단 WinRT가 이렇게 구현되어 있으니, 어쩔 수 없다. 동적으로 생성되는 객체에 대해서 XAML에서 명시적으로 객체를 생성하기 위해서는 Custom IXamlMetadataProvider를 구현해 주어야 한다.   

아래는 필자가 개발 중인 Umc.Core.WinRT.dll 에 포함된 Custom IXamlMetadataProvider이다. 윈도우8 모던 앱을 컴파일할 때 MSBuild는 참조되는 어셈블리의 메타데이터를 검색하여 IXamlMetadataProvider 인터페이스를 구현한 객체를 XamlMetadataProvider.g.cs 코드에 자동으로 추가를 해준다. 그리고 컴파일이 된다.

   

   

   

IXamlMetadataProvider가 필요한 경우의 예시

아마 일반적으로 윈도우8 앱을 개발할 때 이 인터페이스를 구현할 필요는 없다. 하지만, 앱을 캡슐화하려고 하고, IoC(Inversion of Control) Container 등을 활용하고자 하고, 동적인 객체가 필요한 경우라면 이 인터페이스를 구현해야 할 필요가 있을 것이다.   


C#이 지원하는 System.Dynamic.ExpandoObject 객체를 생성한다면 이 객체는 XAML에서 명시적으로 호출을 할 수 없다.   

또, System.Dynamic.DynamicObject 를 구현하는 객체도 마찬가지이다. 아래는 Umc.Core.WinRT에 포함된 코드의 일부이다.

   

위와 같은 코드를 이용하여 동적인 객체를 생성하였다면, 명시적으로 구현한 클래스가 없으므로 당연히 XAML에서도 이 객체를 생성할 수 없다.   

이와 같은 경우에 IXamlMetadataProvider를 구현하면 된다.

   


그 밖에 필요한 것들

아마 WinRT는 윈도우폰7 의 API 보다 더 작다. 작은 만큼 없는 것이 많고, 포기해야 하는 것이 많다. 아래에 나열되는 구현체는 http://umcore.codeplex.com 의 필자가 만든 코드를 WinRT용으로 마이그레이션한 것들이다. 조만간 Umc.Core.WinRT도 공개할 것을 약속한다.   

1. WinRT 설계 자체가 IoC Container를 활용하기 매우 너그럽지 못한 구조이다. 그래서 기본적인 WinRT 구조를 많이 벗어난 구조를 직접 구현해야 했다.      


2. MarkupExtension등을 지원하지 않아 Markup 확장이 불가능하여 다른 형태의 XAML답지 못한 요소나 속성들을 따로 만들어야 한다. MarkupExtension등으로 IoC Container 등과 통합을 쉽게 할 수 있으나, 어쩔 수 없이 필자는 Attached Property로 아래와 같이 구현해야 했다.

또는 아래와 같이 LambdaExpression을 이용하여 동적 Compile() 하여 사용하는 형태로 다음과 같이 사용이 가능토록 할 것이다. 이 경우, 위의 방법보다 더 나은 성능을 보여줄 것이다.

 

3. Frame.Navigation은 객체의 Type으로 뷰를 이동한다. 하지만, 하나의 타입에 두 개의 뷰를 만들 수 있는 APIs 를 제공해 주지 않는다 따라서 INavigationService와 NavigationServiceFrame을 직접 구현하여 다음과 같이 하나의 Type 으로 생성되는 뷰는 여러 개의 뷰 객체를 생성할 수 있도록 했다.

다음과 같이 인터페이스를 정의하였고, 기존의 Windows.UI.Xaml.Controls.Frame은 Umc.Core.ModernApp.NavigationServiceFrame으로 대체하도록 하였고, UniquqKey로 구분하여 하나의 Type에 여러 뷰를 생성하여 네비게이션 할 수 있도록 했다.

   

4. IoC Container와 통합된 EventAggregator

뷰에 이벤트를 전달하거나 전역 이벤트를 전달하기 위해서 좀 쉬운 구조로 가기 위해 IoC Container에 EventAggregator를 함께 넣어보았다. Message 방식을 통해 뷰의 이벤트나 전역 이벤트를 구독할 수 있다.

   

그리고 구독을 뷰에서 제어할 수 있도록 하였다.

   

5. IoC Container와 통합된 인젝션. 객체의 인젝션(Injection-주입)은 다음과 같이 이루어진다.

   

6. IoC Container의 Configuration File 구성

이건 이전에 http://umccore.codeplex.com 에 구현해 놓은 것을 WinRT 용으로 마이그레이션 하였다. patterns & practices - Unity의 경우 Configuration을 지원하지 않지만, UmC Core의 IoC는 이를 한번 더 Wrapping 하였기 때문에 구성 파일로 만드는 것이 가능하다.

   

7. IoC Container에서 지원하는 AOP

이는 WinRT 구조상 이를 구현하기가 그리 쉽지는 않다. WinRT에서는 직접 MSIL(MS Intermediate Language)을 이용하여 런타임에 Instructions을 생성할 수 없다. 다만, APIs 가 모자란 만큼 모자란 대로 구현을 할 수 밖에 없다.

예를 들면, C#의 dynamic 을 이용하여 다음과 같이 구현 가능하겠다.

   

   

다음 버전의 윈도우8 앱 SDK 구조는 또 얼마나 바뀔까 걱정!

실버라이트의 일부와 윈도우 폰7에서도 그러하듯 이번 WinRT도 초기 버전이라는 생각이 든다. 생각해보라. 실버라이트 1,2까지 얼마나 개발자의 Needs를 만족해주지 못하였는지. 앞으로 등장할 윈도우 폰8 개발 SDK도 하위 호환성을 일부 포기한다고 알고 있다.   

현재까지 윈도우8 앱 개발 SDK 환경을 본다면, 기존에 가능하던 것들이 WinRT 환경에서 매우 많은 제약이 따른다는 것이 불편하다. 현재 WinRT와 윈도우8 앱 개발 플랫폼의 구조를 본다면, 차기 개발 SDK에서는 WinRT를 얼마나 개선할 수 있을지 알 수는 없다. 아마 WinRT/SDK를 만드신 분들도 참 많이 고민을 했을 것이다.   

다만 WinRT/SDK를 사용하는 개발자에게 그 동안 밟아왔던 원망스러웠던 수순을 밟지 않기를 바랄 뿐이다. 

어쨌든, 윈도우8 WinRT/SDK의 불합리하거나 불편했던 부분을 필자가 구현한 이전에 공개했던 http://umccore.codeplex.com 에 추가로 공개할 예정이다.

'O/S > Windows 8' 카테고리의 다른 글

윈도우 8, 무서운 드라이버와 궁합  (0) 2013.06.05
윈도우 8, 반토막짜리 WinRT와 WinRT SDK  (1) 2012.10.30
Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 김종남 2016.05.15 21:03 Address Modify/Delete Reply

    글 잘 보았습니다.



알툴바를 아시는지요? Internet Explorer 로 인터넷을 서핑할 때 마우스 오른쪽 버튼을 이용하여 키보드 사용을 최소화할 수 있도록 도와주는 툴입니다. 마우스의 동작을 인식하는 일명 Gesture 기능이지요.
 
이제 Visual Studio 에서도 이 기능을 사용할 수 있습니다.
VSGesture 는 Visual Studio 에서도 마우스의 동작을 인식하여 명령을 할 수 있습니다.

 
VSGesture v1.0
 


다운로드(Download)

이 링크에서 다운로드 받으십시오.

VSGesture 는 Visual Studio Gallary 사이트에서도 찾을 수 있습니다.
 

 
사용방법 : 코드 에디터에서 마우스 오른쪽 버튼을 클릭하고 동작을 그린다!
 
[그림1] VSGesture 실행 화면
 
설치 환경
l Windows Vista 이상
l .NET Framework 3.5 SP1
l Visual Studio 2008 / 2005
 
주요 기능
l 문서 이동
l 빌드
l 디버그
l 문서 제어
 
 
잠깐! VSGesture 는 Windows Vista 이상을 지원합니다.
 
Windows XP 또는 Windows Server 2003 사용자는 아래의 구성 요소를 다운로드 받아야 합니다. 단, 반드시 순서대로 설치하셔야 합니다.
 
Microsoft Windows XP Tablet PC Edition Software Development Kit 1.7
 
Microsoft Windows XP Tablet PC Edition 2005 Recognizer Pack
 
 
 
마우스 동작 사용법
 


 
편리한 VSGesture Visual Studio 와 함께 즐프하세요.

Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 맨날맑음 2009.07.15 13:44 Address Modify/Delete Reply

    이런 유용한 기능이.. 당장 사용해야겠어요

  2. resisa 2009.10.16 09:28 Address Modify/Delete Reply

    오오~ 해외에서 엄청난 반응이 있다는 그 툴 인가요? ^^
    쓰다가 안쓰니까 자꾸 허공에 동그라미를 그리는 1인

  3. kopizzang 2010.03.29 22:39 Address Modify/Delete Reply

    회사에서 쓰고 싶은데;;;
    상업적 목적이 있으면 못쓴다해서;;;;헐;;;
    집에서 사용해야겠습니다.

  4. 태워니 2010.04.26 10:29 Address Modify/Delete Reply

    이런 좋은기능이!!
    감사합니다. 유용히 잘 쓰겠습니다.

  5. blueasa 2010.12.06 19:35 Address Modify/Delete Reply

    좋은 프로그램 감사합니다.
    링크로 퍼갈게요. :)

  6. 작은개발자 2011.05.11 14:48 Address Modify/Delete Reply

    완전 좋아요!!!!

    감사합니다..... 더불어 모델링 문서도 잘 보고 있습니다. ^^

  7. 승훈 2011.12.11 17:08 Address Modify/Delete Reply

    안녕하세요. 이제 막 설치한 유저입니다.
    웹 서핑에서 마우스 제스쳐로 엄청 편리하게 사용하다가 문득 개발툴에도 있으면 어떨까?
    아~~ 혹시 누군가 만들지 않았을까? 해서 찾으니 한국분이. ^^
    정말 감사하게 사용중입니다. 감사드려요 ^^
    다름이 아니라 "빌드 중지" 버튼을 만들수 없을까요?
    아님 Visual Studio에 기능을 원하는 제스쳐로 매핑 기능이 들어가면 최강 될듯해요 ^^
    ㅎㅎ 넘 오버했나봅니다. 계획 있으시면 완전 기다려질거예요 ^^
    그럼 이만~ 훼리릭~~

    • POWERUMC 2011.12.11 21:03 Address Modify/Delete

      잘 사용하신 다니 다행입니다.^^*

      피드백 주신 매핑 기능이 원래 처음 기능에 들어가기로 되어있었는데요.
      VS2010에서 XAML 코드로 XML Nested 매핑하려니 한계가 있더라구요.

      다음 업데이트에는 걍 코드로 매핑해서 사용자가 원하는 명령을 사용할 수 있도록 제공하겠습니다.

      감사합니다.


 
명령 프롬프트(CMD) 를 띄울 필요 없어요!
 
개발하다 보면 여러 개의 명령 프롬프트(Command Prompt) 를 띄우는 일이 생기게 됩니다. 여러 개의 명령 프롬프트를 띄우지 마시고, 이제 VSCmd 를 사용해 보세요. Visual Studio 를 실행하고 도구에서 VSCmd 를 실행하면 명령 프롬프트 기능이 실행됩니다.
 
[그림1] VSCmd 설치 후 도구 명령에서 실행할 수 있다
 
 
명령 프롬프트와 뭐가 틀린가요?
 
잘 아시다시피 Visual Studio 는 도킹(Docking) 기능이 편리하게 잘 되어있습니다. 이런 도킹 기능을 이용하여 여러 개의 명령 프롬프트를 Visual Studio 에서 여러 개 띄워서 사용할 수 있습니다.
 
[그림2] 명령 프롬프트를 여러 개 사용할 수 있다 (클릭하면 확대 됩니다)
 
 
어떤 편리한 기능이 있나요?
 
[그림3] 다양한 옵션
 
l 글자색, 배경색과 글꼴을 바꿀 수 있습니다.
l 탭에 붙혀 크게 볼 수 있습니다.
l 현재 폴더에서 탐색기를 열 수 있습니다.
 
 
Visual Studio 는 모두 지원하나요?
 
Visual Studio 2005 / 2008 버전에서 사용할 수 있습니다.
아직은 기능이 미약하나 사용하시는데 큰 지장은 없습니다^^

'Umc Projects > VSCMD' 카테고리의 다른 글

VSCmd 공개 - Visual Studio 에서 명령 프롬프트를...  (0) 2009.03.01
Posted by 땡초 POWERUMC

댓글을 달아 주세요

예전에 Visual Studio Gallery 에서 본적이 있습니다. 기능이 더 뛰어나지는 않지만 쓰실 분은 그냥 쓰시면 되겠습니다.
 
개발하다 보면 Windows Explorer 를 여러 개 띄워서 사용하는데, 조금 불편해서 만들었습니다. Visual Studio 에서는 Docking 환경이 아주 잘되어 있어서 VSExplorer 를 여러 개 띄워서 아무데나 갖다 Docking 시켜서 사용하심 되겠습니다.
 
저는 Visual Studio 에 호스팅만 했을 뿐, FileView, FolderView 컨트롤을 CodeProject 의 오픈 소스 컨트롤을 가져왔습니다. 근데, FileView 등 Control 로 만들어 지지 않아서 여기에서는 FileView Control 로 만들어서 사용했습니다. 근데 이 오픈 소스에 문제가 있어서 그냥 더 만들려다가 말았습니다 ^^;

Visual Studio 2005 / 2008 ( Professional 이상, 영문/한글 버젼 지원 )
 
[그림1] VSExplorer 설치
 
설치를 하시고 도구->Umc.Core.Tools.VSExplorer 항목을 클릭합니다.
 
[그림2] VSExplorer 실행
 
또는 단축키로 Alt+E 를 사용할 수 있습니다.(이 단축키는 VSExplorer Option 에서 변경하실 수 있습니다)
 
[그림3] VSExplorer 실행 화면 ( 클릭하면 확대 됩니다 )


[그림4] 다양한 활용 방법
 
만들다 보니, 오픈소스 FolderView 컨트롤에 버그도 좀 심각하고, Windows Explorer 와 비슷하게 만들려고 하니 생각보다 훌쩍 끝낼 작업은 아니다 싶어 더 기능 추가할 생각은 없답니다. ^^;
 
Code Project: Adding Drag and Drop to an Explorer Tree Control
 

'Umc Projects > VSExplorer' 카테고리의 다른 글

Umc.Core.Tools.VSExplorer 공개  (0) 2009.01.31
Posted by 땡초 POWERUMC

댓글을 달아 주세요

 
이전부터 Visual Studio 를 쓰면서 최근 프로젝트가 지저분해지면 지우고 싶었는데, 매번 레지스트리를 비우기도 귀찮고 해서, 주말에 집에서 한번 만들어 보았습니다.
 
VSHelper 는 Visual Studio 2005, 2008 Standard 이상에서 사용할 수 있습니다.
 
 
[그림1] 지저분한 Visual Studio 의 최근 프로젝트
 
[그림2] 도구-VSHelper Manager 를 클릭
 
[그림3] 지우고 싶은 항목을 지우고, Visual Studio 를 새로 시작합니다.
 
간단하죠??
아직은 기능이 허접합니다만, 필요한 기능이 생기면 또 집어 넣겠습니다.
 
 
 더불어 Comment Helper 와 함께 사용하시면 더욱 좋습니다 ^_^;
 

'Umc Projects > VSHelper' 카테고리의 다른 글

VSHelper 1.0 - Visual Studio 의 부족함을 채워주는...  (0) 2008.12.15
Posted by 땡초 POWERUMC

댓글을 달아 주세요

1.    Umc.Core 그 이후 5개월
 
[Umc Projects/Umc.Core] - Umc.Core 란? 을 소개한 이후, 벌써 5개월이라는 시간이 흘렀습니다. 많이 바쁘기도 했고, 게으르기도 했고… 정말 뭘 했는지 모르게 벌써 반년이 가깝게 지나갔네요. 사실 완성도를 100% 라고 볼 때, 아직 25% 정도의 진척율 정도 보이질 않고 있습니다. ( 현재 약 8500 Line 나오네요. ) 올 해 안에 끝낼 수 있을지.. Umc.Core 가 여러분들의 기억 속에서 지워지지 않을까 하는 조바심에 미공개 Preview 를 조심스럽게 선보입니다.
 
그럼 어떤 모습으로 Umc.Core 가 진행되고 있을까요?
 
 
1.1. 중앙관리 패턴의 Sitemap MVC
 
Webform 과 Winform 등의 시스템 모든 구조를 XML 로 관리되는 MVC 패턴의 Sitemap 입니다.
 
[그림1] Sitemap MVC 패턴의 다이어그램
 
분산된 각 시스템 구조 및 정보를 XML 로 관리하고, MVC Framework 의 Route 의 기능이 통합되어 있습니다. 이 Sitemap MVC 는 상위 노드에 대한 하위 노드 상속성으로 인해 전체 사이트의 MasterPage 를 변경 한다던지, 일부 또는 그 하위 구조에 대한 공통 매개변수를 적용하는 것들에 대해 상당히 유연하게 관리할 수 있습니다. 또한, 모든 매개변수는 XML 에서 관리하게 되므로, 불필요한 URL QueryString 을 줄일 수 있습니다.
 
 
1.2. Umc.Core.Web     
 
혼자 개발하는 프레임웍이라 그 동안 불편하다고 느낀 것, 시도해 보고 싶은 것을 모두 적용해 보려고 하고 있습니다. Umc.Core.Web 은 현재 가장 많은 진척율을 보여주고 있답니다.
 
[그림2] Umc.Core.Web 어셈블리의 다이어그램
 
Umc.Core.Web 은 Sitemap MVC 와 연동이 되며, MasterPageBase, UserControlBase, PageBase 등의 주요 클래스가 자리잡고 있습니다. 이것은 어떤 형태의 페이지라도 일관성 있는 코딩을 가능하게 해주고 있습니다.
 
특히, Umc.Core.Web 에는 ParamMember 기능을 제공해 주고 있습니다. ParamMember 는 제가 꼭 넣고 싶었던 기능 중에 하나인데, 페이지간의 값 전달을 자동화 해주는 기능입니다. 페이지간에 ParamMemberAttribute 을 맴버 변수에 특성을 선언해 주기만 하면, 불필요한 코딩 없이 맴버 변수의 선언만으로 QueryString 을 받을 수 있고, 보낼 수 있는 기능입니다. Get/Post 전송을 지원하며, QueryString 의 암호화도 지원합니다.
 
이 외에도, Umc.Core.Web.Controls 도 계획중이며, 실무에서 필요한 다양한 Custom Controls 과 함께 표준 컨트롤을 지원할 예정입니다.
 
 
1.3. Umc.Core.Web.WebService
 
네이밍에서 알 수 있듯이 XML WebService 를 위한 어셈블리입니다. 현재 Soap Body 의 암호화와 압축을 지원하며, Soap Header 인증에 대한 부분도 구현예정입니다.
 
 
1.4. Umc.Core.License
 
Umc.Core Framework 에 대한 라이센스 어셈블리입니다. 추후, 오픈소스로 공개할 예정이기에, Umc.Core 의 배포 수준/사용율 등의 통계를 내기 위한 어셈블리 입니다. 하지만, 주된 목적은 상업적인 용도로 사용되는 것을 방지하기 위한 Framework 사용자의 추적 용도라고 보시면 될 것 같습니다.
 
 
1.5. Umc.Core.Diagnostics.Logger
 
Umc.Core Framework 를 이용하여 개발하는 동안의 Trace 를 기록할 수 있는 Logger 입니다. 현재, TextLoggerProvider 와 XmlLoggerProvider 가 완료되었습니다. 특히, XmlLoggerProvider 는 Xml Style Sheet 를 이용하기 때문에 로그 유형에 따라 컬러풀하게 시각적으로 로그를 관찰 할 수 있습니다.
 
[그림3] Umc.Core.Diagnostics.Logger 어셈블리 다이어그램
 
[그림3] 에서 볼 수 있듯이, MsSql / Oracle 데이터베이스의 Logging 도 지원할 예정입니다. 어떤가요?? 정말 할일 많이 보이죠? ㅡㅜ;
 
 
2.    추후 작업 예정
 
아직 개발 진척율이 25% 라고 이미 말씀드렸습니다. 한 것보다, 해야할 것이 더 많습니다. 추후 작업 예정을 통해 어떤 모습으로 Umc.Core 가 될지 상상할 수 있을 것입니다.
 
Umc.Core.Configuration.Install 어셈블리는 어셈블리는 Umc.Core Framework 인스톨시에 Visual Studio 를 Migration 하는 클래스 입니다. 자연스럽게 Visual Studio 와 Umc.Core 를 통합할 수 있도록 설치를 도와줄 예정입니다.
 
Umc.Core.Administration 어셈블리는 어셈블리는 다양한 관리를 도와줄 것입니다. Active Directory / IIS / File System 등 사용상의 편의를 위해 Wrapper 클래스를 준비할 예정입니다.
 
Umc.Core.Security 는 제가 보안쪽에 아무런 관심이 없기 때문에, Enterprise Library 를 Wrapping 할 예정입니다^^;
 
또한, Comment Helper 와 Smartclient Debugger 를 좀 더 업그레이드 하여 Umc.Core 와 함께 배포할 예정이며, 특히 Comment Helper 는 Visual Studio 구동이 느려진다는 제보에 따라, 기능별로 Addin 형태로 사용할 수 있도록 구조를 변경할 예정입니다.
 
개인적으로 넣고 싶은 기능들이 많고, 아직은 이렇다할 완성도를 보여주고 있지 못하기 때문에 소스코드는 좀 더 개발 후에 Preview 로 공개할 예정이랍니다.
 
 
엄준일은 정말 값진 경험을 하고 있습니다

 
제가 하고 있는 이 짓에 대해 누군가는 말할 수 있을 것 같습니다. 이 말을 하고 싶어서, 이 포스팅을 하였습니다. 누군가는 저에게 “많이 거만해졌다”, “쥐뿔도 모른 것이…”, “경력이 어쩌고…”. 저를 평가할 정도이면, 아마도 언젠가는 이 포스팅도 볼 거라고 생각합니다.
 
누군가 저에게 하는 말.. 모두 맞는 말입니다. 닷넷을 배우면서 초심을 많이 잃었고, 쥐뿔도 모르면서 잘난 척 하고, 경력도 완전 짧습니다. 하지만, 시대는 이미 다릅니다. 많이 알고, 얇은 팁을 혼자만 알고, 자신만의 4차원에서 노는 것 보단, 잘나지 않은 지식을 뽐낼 수 있는 이 Umc Blog가 좋습니다.
 
제 공간입니다!!”
 
저의 사생활이나 지식의 깊이를 재고 비난하시려는 분은 정중히 이 블로그를 떠나 주십시오.
 
전 당신들과 같은 고수들을 위한 Umc Blog 가 아닙니다. Umc.Core 도 당신들과 같이 고수삘 나는 Framework 도 아닙니다. 오픈 소스로써 재 가치를 다하고, 더 나아가 좀 더 나은 가이드를 받기 위한 것입니다. 제발 오바 하지 마세요.
 
누군가는 분명, “시작이 반이다.”, “경험이 재산이다” 라고 합니다. 이 글귀 하나로, 많은 개발자들이 IT 에 뛰어들고 노력하고 있다는 것을 명심하십시오.

'Umc Projects > Umc.Core' 카테고리의 다른 글

Umc Core IoC 통합 컨테이너 #1  (0) 2013.05.24
Umc.Core 프레임워크 다이나믹 프록시(Dynamic Proxy) #1  (0) 2013.05.23
Umc.Core 미공개 Preview  (6) 2008.05.14
Umc.Core 란?  (0) 2007.12.01
Posted by 땡초 POWERUMC
TAG Umc.Core

댓글을 달아 주세요

  1. 태디 2010.01.12 21:25 신고 Address Modify/Delete Reply

    누군가가 누군지 알고 있지 ㅋ
    뻘글^^


    반도체에서 1년간 신규시스템
    인계 받아서 추가개발만 하다보니
    실력은 안늘고 잡기술만 늘었네.. ㅋ

    작년 10월에 스타트했던 신규플젝도
    이달 말이면 끝나고 반도체도 어느덧
    계약 만료 시간이 다되가네...

    2월에 끝나거든 그럼 그 이후에는
    준일이 얼굴 볼 수 있을 것 같다^^
    PS) 3월에 서울로 이사갈 예정

    • 엄준일 2010.01.12 23:29 Address Modify/Delete

      허허.. ㅋㅋ
      얼른 서울로 이사왕~
      울 동네루~
      얼굴좀 자주보장..... 넘 못본지 오래된 것 같네

  2. 노땅 2010.04.01 11:27 Address Modify/Delete Reply

    만드신 소스 보면서
    큰 도움이 되었습니다. ^^;

  3. 연성호 2012.04.04 09:46 Address Modify/Delete Reply

    고생 많으시네요~ ^^ 일단 시작하신 용기에 박수~! ^^

    • 엄준일 2012.04.04 18:08 Address Modify/Delete

      감사합니다.^^;
      이게 v1.0 버전이고, 버전을 거듭하여 현재 v3.0까지 와써용

  4. 태산 2012.09.16 12:27 Address Modify/Delete Reply

    관심병자들보다 엄준일님에게 도움받는 사람들이 훠어어얼씬 많습니다. 수고하십쇼!

오래전부터 생각하고 있었던 계획의 첫발을 드디어 내딛었습니다.
친구들과 놀아야 하고, 술도 마셔야 하고, 공부도 해야하고, 블로그도 관리해야 하고, 회사일도 해야하고… 정말 할 일이 많네요. 하지만 이런 할일들은 무성하지만, 실천으로 옮겨지지 않는다면 무슨 의미가 있겠습니까?
 
Umc.Core 란?
간단히 말해서 Framework 입니다. 예전부터 만들었던 것을 재사용성이 더욱 용이하게 만들고, 편리한 기능들의 총집합체입니다. C# 3.0 기반으로 컨버젼 중이며, 기대하셔도 좋습니다.
현재는 기존에 만들어두었던 소스를 합치고 다듬는 과정에 있으며 추후 지속적으로 개인적으로 진행할 프로젝트 입니다.
또한, 차후 Umc.Core 는 오픈 소스로 여러분께 공개될 것입니다. 그 과정에 중간중간 아티클로 직접 제작해 볼 수 있는 포스팅도 쓸 예정입니다.
차차 Winform, Webform, Distributed Processing, Silverlight, .NET Framework 3.0 을 지원할 계획입니다.
 
[그림0] Umc.Core 개발중인 솔루션
 
 
Umc SmartClient Debugger Tool v1.0
기본적인 Umc.Core 의 빼대와 함께 첫번째로 지원하게 될 툴은 스마트클라이언트 디버거” 툴입니다. 약 60% 개발진행 상태이고 현재는 스크릿 샷만 공개하도록 하겠습니다.
 
[그림1] Umc 스마트클라이언트 디버거 툴 v1.0
 
 
앞으로 계획
제가 똑똑하지만은 않기 때문에, 이것저것 공부를 하면서 개발하게 될것입니다. 회사일 끝나고 밤에 조금씩 개발할 생각이라 후딱후딱 해치우진 못할 것 같네요~ 하지만 큰 포부를 갖고 시작하는 일이니 반드시 끝을 볼 생각이구요. 저의 가장 훌륭한 포토폴리오가 되길 스스로 기원해 봅니다.

'Umc Projects > Umc.Core' 카테고리의 다른 글

Umc Core IoC 통합 컨테이너 #1  (0) 2013.05.24
Umc.Core 프레임워크 다이나믹 프록시(Dynamic Proxy) #1  (0) 2013.05.23
Umc.Core 미공개 Preview  (6) 2008.05.14
Umc.Core 란?  (0) 2007.12.01
Posted by 땡초 POWERUMC

댓글을 달아 주세요