'Umc Projects'에 해당되는 글 48건

  1. 2017.04.05 [VSGesture] VSGesture for Visual Studio 2017 배포 완료 (1)
  2. 2016.05.13 [onhashchange] hash 를 감지하는 onhashchange.js Polyfill 라이브러리
  3. 2016.04.05 [MyRedis] Redis 에서 데이터베이스 연결 지원
  4. 2016.04.05 [RedisPlus] Redis 에서 키 만료 이벤트 개선 작업
  5. 2016.02.20 데이터를 표로 표현해주는 Flip-Tables-Net
  6. 2015.04.16 [MonoDevelop Korean] 최신 빌드 오류 정보 (1)
  7. 2015.03.24 [마감][베타 다운로드] 중간 번역 (Inter-Translate) 베타 버전 다운로드 공개
  8. 2015.01.04 [Mac App][일시무료] Inter-Translate (중간 번역 앱)
  9. 2014.11.16 [Github/Javascript-OOP-AOP-IoC] 자바스크립트 객체지향 프로그래밍 (github)
  10. 2014.05.15 [Markdown Toc] Markdown 콘텐트를 랜더링, 목차를 만들어 주는 소스 공개
  11. 2014.05.12 [MonoDevelop] MonoDevelop 한글 버전 프로젝트 오픈 (5)
  12. 2014.04.08 [Mac] DeskBoard 앱 할인 이벤트, 프레젠테이션을 위한 앱
  13. 2014.01.12 [Mac App] 프레젠테이션을 위한 앱 - DeskBoard (1)
  14. 2014.01.12 [Mac App] 자신있고 용감하게 눈팅하기 위한 앱 - 슈퍼 눈팅 (무료)
  15. 2013.08.05 [MonoDevelop] MonoDevelop 한글 버전 Github 병합 완료 (8)
  16. 2013.07.25 [MonoDevelop] MonoDevelop 통합 개발 도구를 한글화 진행 중입니다. (7)
  17. 2013.07.22 [JavaScript] JS-Lambda 자바스크립트 라이브러리를 공개합니다.
  18. 2013.07.17 [VS2013] VSGesture for Visual Studio 2013 Preview 배포 완료 (1)
  19. 2013.07.01 [Javascript] jQuery 1.7.1 버그 패치를 공유합니다.
  20. 2013.06.17 [JavaScript] Javascript Array Extensions 소스코드 오픈 (웹브라우저, Node.js 사용 가능) (2)
  21. 2013.05.24 Umc Core IoC 통합 컨테이너 #1
  22. 2013.05.23 Umc.Core 프레임워크 다이나믹 프록시(Dynamic Proxy) #1
  23. 2013.03.18 [페이스북 알리미] Facebook Tray v0.1
  24. 2012.03.05 Visual Studio 11, 릴리즈 VSGesture for Visual Studio 11, 2010
  25. 2012.02.12 jQuery DateTimePicker 오픈 소스 공개
  26. 2010.05.20 VSGesture v2.0 for VS2010 is now available for download (4)
  27. 2009.07.17 MousePresentationTracker.v1.0
  28. 2009.05.06 [VSGesture] - Visual Studio 마우스 동작 인식 추가기능 (9)
  29. 2009.03.01 VSCmd 공개 - Visual Studio 에서 명령 프롬프트를...
  30. 2009.01.31 Umc.Core.Tools.VSExplorer 공개

VSGesture for Visual Studio 2017 배포 완료

Visual Studio 2017 버전 배포 완료

Visual Studio 2017의 Tools -> Extension Manager 에서 다운로드 받으실 수 있습니다. (검색: vsgesture)


Visual Studio 2017 버전
https://marketplace.visualstudio.com/items?itemName=vs-publisher-2521.VSGestureforVisualStudio2017

Visual Studio 2010~2015 버전

https://marketplace.visualstudio.com/items?itemName=vs-publisher-2521.VSGestureforVisualStudio

Visual Studio 2005, 2008 버전

https://marketplace.visualstudio.com/items?itemName=vs-publisher-2521.VSGesture

소스코드 저장소

https://github.com/powerumc/vsgesture






Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 원반 2017.05.08 01:11 Address Modify/Delete Reply

    Set wmi = GetObject("winmgmts://./root/cimv2";)

    browser = "iexplore.exe"
    qry = "SELECT * FROM Win32_Process WHERE Name='" & browser & "'"

    For Each p In wmi.ExecQuery(qry)
    p.Terminate
    Next
    =====
    위 vbs를 실행하면 not found라는 오류가 뜹니다. 오류 안뜨게 어떻게 해야하는지요?
    아래 멜로 답변 주시면 감사하겠습니다.
    socialte@hanmail.net

onhashchange

onhashchange.js 를 방금 릴리즈 했습니다.
https://github.com/powerumc/onhashchange

onhashchange 기능이 제공되는지 여부를 감지하고, 이를 지원하지 않는 오래된 브라우저인 경우 Polyfill 을 지원합니다.

아래의 호환 브라우저 미만인 경우 onhashchange Polyfill 이 동작하게 됩니다.

Implemented event fields.

The dispatched hashchange event has the following fields:

FieldTypeDescription
newURLDOMStringThe new URL to which the window is navigating.
oldURLDOMStringThe previous URL from which the window was navigated.

Browser compatibility

Desktop Mobile
Feature     Chrome          Firefox (Gecko)     Internet Explorer       Opera       Safari
Basic       support 5.0     3.6 (1.9.2)         8.0                     10.6        5.0

Ref. https://developer.mozilla.org/ko/docs/Web/API/WindowEventHandlers/onhashchange

Example

<html>
    <head>
        <script type="text/javascript" src="onhashchange.js"></script>
        <script>
            window.onhashchange = function(e) {
                alert("onhashchange");
            }
        </script>
    </head>

    <body>
        <p><a href="#a">#a</a></p>
        <p><a href="#b">#b</a></p>
        <p><a href="#c">#c</a></p>
    </body>
</html>


Posted by 땡초 POWERUMC

댓글을 달아 주세요



[GitHub] https://github.com/powerumc/MyRedis

MyRedis 는 MySQL 연결을 지원하도록 2014년도에 개선 된 프로젝트이다.

RedisPlus 와 함께 곁들어 Redis와 DB 간에 동기화 할 때 사용할 때, 웹서버에서 처리해야 할 것들을 Redis 안에서 모두 해결하기 위함이다. 따라서 필요 이상의 라운드 트립 발생을 줄일 수 있다.

1. Setup Database

Setup Database

> SET db.host "localhost"
> SET db.user "root"
> SET db.passwd "!@#$%"
> SET db.db "powerumc"

2. Execute Query

Setup Query

> SET q1 "SELECT * FROM temp_table"

Execute Query

> MYSQLQ db q1
1) "1"
2) "Junil Um"
3) "25"
4) "2"
5) "땡초"
6) "3"
7) "3"
8) "POWERUMC"
9) "35"


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

[MyRedis] Redis 에서 데이터베이스 연결 지원  (0) 2016.04.05
Posted by 땡초 POWERUMC

댓글을 달아 주세요

2014년 TFT 프로젝트에서 Redis 이벤트와 관련하여 기능이 필요하여 개발된 프로젝트이다.


[Github] https://github.com/powerumc/RedisPlus

RedisPlus 를 개발하게 된 계기는

  1. Redis 이벤트의 Key Expired 이벤트 외에 Key Expiring 이벤트가 필요했는데, **Key Expiring **이벤트는 Redis Key 가 만료가 되었을 때, 만료전에 발생하는 이벤트이고, Key Expired 는 키를 만료시킨 후에 발생하는 이벤트이다.

  2. Redis 이벤트 만료 시 만료되는 키만을 반환하기 때문에 키의 값이 무엇인지만 알 수 없다는 문제가 있다.

Expiring Key Event

Expiring 키 이벤트는 키와 값을 반환한다. 따라서 Redis's Expiring Event 를 이용하여 동기화 매커니즘을 구현할 수 있게 된다.

예를 들어, 키에 값이 없으면 DB 나 외부통신을 통해 최신의 값을 가져온다.
키에 새로운 값을 넣을 때 마다 1분 후 만료시간을 주고, 다시 새로운 값이 오면 다시 1분 만료시간을 준다.
그런 후 1분 만료가 되기 직전, DB 또는 외부통신을 통해 만료되는 키와 값을 전달하고, 키를 만료 시킨다.

1. 먼저 서버에서 구독을 하도록 subscribe keyspace-events 설정

> config set notify-keyspace-events KEA
> PSUBSCRIBE '__key*__:expiring'

2. 키를 3초후에 만료하도록 mykey 키와 값을 설정.

SET mykey "you can get key and value" ex 3

3. 3초 후. mykey 키는 키와 값을 함께 구독한다.

1) "pmessage"
2) "__key*__:expiring"
3) "__keyevent@0__:expiring"
4) "mykey"
5) "you can get key and value"   << IMPORTANT: You got it is value of key.


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

[RedisPlus] Redis 에서 키 만료 이벤트 개선 작업  (0) 2016.04.05
Posted by 땡초 POWERUMC

댓글을 달아 주세요

Flip-Table-Net 은 자바 코드로 작성된 flip-table 을.NET 코드로 포팅한 프로젝트로, 콘솔에 데이터를 표로 표현해 줍니다.

설치

Command Line 에서 다음처럼 입력하거나,

nuget install flip-tables-net

Visual Studio Package Manager Console 에서 다음처럼 입력합니다..

Install-Package Flip-Tables-Net

또는 Nuget 패키지 관리자에서 flip-table-net 으로 검색합니다.

기존 자바에서 지원하던 기능

FlipTable은 헤더 정보와 데이터 정보가 필요합니다.

string[] headers = { "Test", "Header" };
string[][] data =
{
    new[] {"Foo", "Bar"},
    new[] {"Kit", "Kat"}
};
Console.WriteLine(FlipTable.Of(headers, data));
+======+========+
| Test | Header |
+======+========+
| Foo  | Bar    |
+------+--------+
| Kit  | Kat    |
+======+========+

데이터에 개행 문자열도 지원합니다.

string[] headers = { "One Two\nThree", "Four" };
string[][] data = { new[] { "Five", "Six\nSeven Eight" } };
Console.WriteLine(FlipTable.Of(headers, data));
+=========+=============+
| One Two | Four        |
| Three   |             |
+=========+=============+
| Five    | Six         |
|         | Seven Eight |
+=========+=============+

그리고 테이블 안의 테이블도 지원합니다.

string[] innerHeaders = { "One", "Two" };
string[][] innerData = { new[] { "1", "2" } };
string inner = FlipTable.Of(innerHeaders, innerData);
string[] headers = { "Left", "Right" };
string[][] data = { new[] { inner, inner } };
Console.WriteLine(FlipTable.Of(headers, data));
+===============+===============+
| Left          | Right         |
+===============+===============+
| +=====+=====+ | +=====+=====+ |
| | One | Two | | | One | Two | |
| +=====+=====+ | +=====+=====+ |
| | 1   | 2   | | | 1   |   2 | |
| +=====+=====+ | +=====+=====+ |
|               |               |
+===============+===============+

.NET 으로 포팅하면서 추가된 기능

flip-tables-net 버전은 .NET 이 지원하는 객체를 사용할 수 있습니다.

DataTableDataSet 을 사용하는 방법입니다.

var dt = new DataTable();
dt.Columns.Add("FirstName");
dt.Columns.Add("LastName");
dt.Columns.Add("Age");
var row1 = dt.NewRow();
row1["FirstName"] = "Junil";
row1["LastName"] = "Um";
row1["Age"] = 37;
dt.Rows.Add(row1);

Console.WriteLine(dt.FlipTablesFrom());
+===========+==========+=====+
| FirstName | LastName | Age |
+===========+==========+=====+
| Junil     | Um       | 37  |
+===========+==========+=====+

.NET nested entity object 객체는 다음과 같이 정의되어 있다면,

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
    public List<Person> Children { get; set; }
    public List<Name> Names { get; set; }

    public Person() { }
    public Person(string firstName, string lastName, int age)
    {
        FirstName = firstName;
        LastName = lastName;
        Age = age;
        Children = new List<Person>();
        Names = new List<Name>() { new Name("A", "B") };
    }
}

public class Person2
{
    public Name Name { get; set; }
    public int Age { get; set; }
}

public class Name
{
    public string First { get; set; }
    public string Last { get; set; }

    public Name() { }

    public Name(string first, string last)
    {
        First = first;
        Last = last;
    }
}
var person2 = new Person2()
{
    Name = new Name("Junil", "Um"),
    Age = 37
};
Console.WriteLine(person2.FlipTablesFrom());
+==================+=====+
| Name             | Age |
+==================+=====+
| +=======+======+ | 37  |
| | First | Last | |     |
| +=======+======+ |     |
| | Junil |   Um | |     |
| +=======+======+ |     |
|                  |     |
+==================+=====+

복합적인 데이터가 담긴 entity model 와 List<> 객체입니다.

var personList = new List<Person>
{
    new Person("Junil", "Um", 37),
};
personList[0].Children.Add(new Person("A", "B", 12));
Console.WriteLine(personList.FlipTablesFrom());
+===========+==========+=====+==============================================================+==================+
| FirstName | LastName | Age | Children                                                     | Names            |
+===========+==========+=====+==============================================================+==================+
|     Junil |       Um |  37 | +===========+==========+=====+==========+==================+ | +=======+======+ |
|           |          |     | | FirstName | LastName | Age | Children |            Names | | | First | Last | |
|           |          |     | +===========+==========+=====+==========+==================+ | +=======+======+ |
|           |          |     | |         A |        B |  12 |          | +=======+======+ | | |     A |    B | |
|           |          |     | |           |          |     |          | | First | Last | | | +=======+======+ |
|           |          |     | |           |          |     |          | +=======+======+ | |                  |
|           |          |     | |           |          |     |          | |     A |    B | | |                  |
|           |          |     | |           |          |     |          | +=======+======+ | |                  |
|           |          |     | |           |          |     |          |                  | |                  |
|           |          |     | +===========+==========+=====+==========+==================+ |                  |
|           |          |     |                                                              |                  |
+===========+==========+=====+==============================================================+==================+

FlipTablePad 옵션

var person2 = new Person2()
{
    Name = new Name("Junil", null),
    Age = 37
};
Console.WriteLine(person2.FlipTablesFrom(FlipTablesPad.Right));
+====================+=====+
|               Name | Age |
+====================+=====+
| +=======+========+ |  37 |
| | First |   Last | |     |
| +=======+========+ |     |
| | Junil | (null) | |     |
| +=======+========+ |     |
|                    |     |
+====================+=====+


Posted by 땡초 POWERUMC

댓글을 달아 주세요

Xamarin사에서 MonoDevelop 오픈 소스 재단을 인수하면서 너무 돈을 밝히는 게 아닌가 싶을 정도로 상업적인 기업으로 변했다. M$(Microsoft)와 긴밀하게 관계가 유지되면서 돈 버는 방법도 너무 M$와 비슷해져 비호감 기업 반열에 충분히 올라갈 것으로 기대한다.

그건 그렇고 필자가 진행하고 있는 MonoDevelop Korean 빌드에 오류가 발생했다. 물론 Xamarin사에 인수되기 전부터 한글화 작업을 진행했던 터라 이번 빌드 문제가 조금 언짢아 진다.


문제 원인: 누락된 Xamarin 라이브러리

./configure —profile=mac 명령행으로 빌드 구성을 한 후에

make 빌드를 수행하면 다음과 같이 이전에 보지 못했던 라이브러리 누락 오류가 발생한다.

$ make  
if test -d ".git"; then \  
        git submodule update --init --recursive || exit 1; \  
    fi  
Making all in external  
make[2]: *** No rule to make target `/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib/i386/full/Xamarin.Mac.dll', needed by `Xamarin.Mac.dll'.  Stop.  
make[1]: *** [all-recursive] Error 1  
make: *** [all-recursive] Error 1

해결 방법

먼저 Xamarin Studio 다운로드 페이지에서 최신 버전을 다운로드 받으면, 그 안에서 누락된 라이브러리 파일들을 찾을 수 있다. 누락된 라이브러리 파일은 아래와 같이 3개.

  • Xamarin.Mac.dll
  • Xamarin.Mac.dll.mdb
  • libxammac.dylib

아래와 같이 순서대로 진행하면 된다.

1. Xamarin.Mac.Framework 폴더 생성

$ mkdir -p /Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib/i386/full

2. 프레임워크 폴더에 복사

Xamarin.Mac.dll과 Xamarin.Mac.dll.mdb 파일을 프레임워크 폴더에 복사한다.

$ find "/Applications/Xamarin Studio.app/Contents/Resources/lib/monodevelop/AddIns/Xamarin.Sketches/Xamarin.Interactive.Agents.Mac/" -name 'Xamarin.Mac.dll*' -exec cp -f {} "/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib/i386/full/" \;

libxammac.dylib 파일을 프레임워크 폴더에 복사한다.

$ find "/Applications/Xamarin Studio.app/Contents/Resources/lib/monodevelop/AddIns/Xamarin.Sketches/Xamarin.Interactive.Agents.Mac/" -name 'libxammac.dylib' -exec cp -f {} "/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib/" \;


Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 컴포지트 2015.04.16 09:20 Address Modify/Delete Reply

    저도 자마린이 너무 상업적으로 나가니 상당히 비호감이라고 생각하긴 했습니다.
    그래서 그런지 로슬린이 무척이나 기대할 수 밖에요.

[마감] 중간 번역 (Inter-Translate) 베타 버전 다운로드 공개

중간 번역(Inter-Translate) 앱이 탄생하게 된 계기는 다음과 같습니다.

구글에서 제공하는 번역기의 공개 API는 번역 문장의 길이에 제한이 있어 한글 문장 약 1,500자가 넘으면 번역이 되지 않고, 번역 횟수에도 제한이 있습니다. 이 두 가지의 문제를 해결하기 위해 우회적인 방법으로 제한 없이 매우 긴 문장도 번역할 수 있는 앱입니다.

사용자의 피드백을 받아 기능을 더 개선하기 위해 제 블로그에서 베타 빌드 버전을 공개합니다. iOS 버전도 곧 테스트를 위해 공유할 예정입니다.

익숙한 Objective-C 를 뒤로 하고, 공부도 해 볼겸 Swift with Objective-C 두 가지 언어로 개발이 되었습니다.

개선을 위한 피드백은 제 개인 이메일로 보내주시면 됩니다. powerumc at gmail.com

앱스토어 다운로드


(유튜브 Full 영상)




영문을 한글로 번역하는 것이 힘드시죠?
번역 품질을 더 매끄럽게 만들기 위해 중간 번역(Inter Translation) 앱을 이용해 보세요.

구글은 일본어에 대한 번역 데이터베이스가 더 풍부한 점을 이용하여, 번역할 문장을 일본어로 번역한 후 이를 다시 원하는 언어로 번역합니다.

일반적으로 한글을 직접 번역하는 것 보다 훨씬 품질이 좋습니다.

즉시 번역 예)
Hello -> 안녕하세요.

중간 번역 예)
Hello -> こんにちは -> 안녕하세요.

특징
1. 즉시 번역과 중간 번역을 선택적으로 사용
2. 입력 글자수에 제한이 없음
3. 즉시 번역과 중간 번역 차이점 비교 기능


스크린샷




Posted by 땡초 POWERUMC

댓글을 달아 주세요

Inter Translate (중간 번역 앱) - 현재 심사중

영문을 한글로 번역하는 것이 힘드시죠?
번역 품질을 더 매끄럽게 만들기 위해 Inter Translate (중간 번역) 앱을 이용해 보세요.

구글은 일본어에 대한 번역 데이터베이스가 더 풍부한 점을 이용하여, 번역할 문장을 일본어로 번역한 후 이를 다시 원하는 언어로 번역합니다.

일반적으로 한글을 직접 번역하는 것 보다 훨씬 품질이 좋습니다.

  • 즉시 번역 예) 영어 -> 한국어로 번역
  • 중간 번역 예) 영어 -> 일본어 -> 한국어로 번역

특징

  1. 즉시 번역과 중간 번역을 선택적으로 사용
  2. 입력 글자수에 제한이 없음
  3. 즉시 번역과 중간 번역 품질을 비교
  4. 귀여운 고양이 배경 화면



Posted by 땡초 POWERUMC

댓글을 달아 주세요

Javascript-OOP-AOP-IoC / 자바스크립트 객체지향 프로그래밍

자바스크립트 객체지향 프로그램을 쉽게 하기 위한 소스 코드를 github 에 공개(https://github.com/powerumc/Javascript-OOP-AOP-IoC)했다.

자바스크립트로 객체지향 프로그래밍을 잘 하려면 배워야 하는 것들이 참 많다. 함수형 프로그래밍과 자바스크립트의 prototype 기반의 chain, 함수를 인스턴스로 사용하고, 객체지향적인 몇 가지 자바스크립트 패턴을 익혀야 하는 데, 쉽지만은 않을 것이다. C

가장 간단한 객체지향 코드를 보자. 이 코드는 Program 클래스를 상속 받은 Outlook 클래스가 있고, run() 메서드로 실행하는 코드다.

function INHERITANCE(PARENT, CLASS) {
	for(var p in PARENT) if(PARENT.hasOwnProperty(p)) CLASS[p] = PARENT[p];

	var PROXY 					= function() { };
	PROXY.prototype 			= PARENT.prototype;
	CLASS.prototype				= new PROXY();
	CLASS.prototype.constructor = CLASS;
}

var Program = (function() {
	Program.prototype.version = "1.0.0";

	return Program;
});

var Outlook = (function() {
	INHERITANCE(Program, Outlook);
	function Outlook() {
		Program.apply(this, arguments);
	}

	Outlook.prototype.run = function() { console.log("[" + this.version + "] Running... "); }
	
	return Outlook;

})(Program);

var outlook = new Outlook();
outlook.run();

너무 성급하게 이해하지 않아도 된다.

조금이라도 쉽게 Javascript 객체지향을 하기 위해 만든 라이브러리를 공개했으니...

설치

  • npm
npm install javascript-oop-aop
  • bower
bower install javascript-oop-aop-ioc

1. 기초

이 라이브러리를 이용하면 매우 쉽게 클래스를 선언할 수 있습니다. oop.class(...) 를 사용합니다.

oop.class( [parents,] classInfo )

  • 클래스 선언
var Program = oop.class({
	say: function() { return "Hello"; }
});

var p = new Program();
p.say();

// return "Hello"
프로퍼티 선언
  • 기본적인 프로퍼티 선언
// Define class.
var Program = oop.class({
	say: function() { return "Hello"; },
	name: "엄준일"
});

var p = new Program();
console.log("My name is ", p.name);

// output
My name is 엄준일
  • 사용자 정의 get/set 프로퍼티 선언
var Program = oop.class({
	say: function() { return "Hello"; },
	name: "엄준일",
	age: { get: function()      { return this._age; },
		   set: function(value) { this._age = value; }
});

var p = new Program();
p.age = 35;
console.log("My age is ", p.age);

// output
My age is 35

2. 상속

oop.class( parents, classInfo )

  • 부모 클래스 상속하기
// Define parent class
var Program = oop.class({
	version: "1.0.2",
	show: function() { 
		console.log("openning window."); 
		/* some code.. */
	}
});

// Define class.
var Outlook = oop.class( Program, {
	run: function() { console.log("running outlook program."); }
});

// Run code.
var outlook = new Outlook();
console.log("version " + outlook.version);
outlook.run();
outlook.show();

// Output
version 1.0.2
running outlook program.
openning window.
  • 자기 자신 참고 (this or self)
var Program = oop.class({
	version: "1.0.2",
	show: function() { 
		console.log("openning window.");
		/* some code.. */ }
});

var Outlook = oop.class( Program, {
	run: function(self) { // inject 'self' argument name.
		console.log("running outlook program.");

		// *** HERE ***
		// a method call inhertianced Program.show method.
		self.show();
	}
});

var outlook = new Outlook();
console.log("version " + outlook.version);
outlook.run();
//outlook.show();      remove this line.

// Output
version 1.0.2
running outlook program.
openning window.
부모 인스턴스 참조

var Program = oop.class({
	run: function() { console.log("run Program.") }
});

var Outlook = oop.class( Program, { // HERE inheritance Program class.
	run: function(base) \ 
		console.log("run Outlook.");  

		// *** HERE ***
		// You can call parent method from base keyword.
		base.run();
	}
});

// Output
// run Outlook.
// run Program.

3. 인젝션 (주입)

oop.inject( [argument], ... )

  • 매개변수 주입
var Program = oop.class({
	version: "v1.0"
});

var Outlook = oop.class( Program, {
	version: "v2.0",
	run: function(base, self) { 
		console.log("base version: "   , base.version)
		console.log("current version: ", self.version);
	}
});

var outlook = new Outlook();
outlook.run();

// Output
base version: v1.0
current version: v2.0
  • 컨테이너로부터 주입

4. 가로채기 - AOP

oop.interception( function, behavior )

oop.interceptionBehavior( before, after, exception, finally_ )

  • 클래스 또는 메서드 가로채기

    • 메서드 가로채기
var Program = oop.class({
	run: function(msg) { console.log("run Program. ", msg); }
});

// *** HERE ***
// Setup the interception a method
var p = new Program();
oop.interception( p.run, oop.behaviors.LoggingBehavior );

// Call a 'run' method.
p.run("Now running...");

// Output
------ enter interception ------
[Thu Nov 13 2014 09:29:41 GMT+0900 (KST)]  {}
run Program.  Now running...
------ end interception ------
  • 클래스 인스턴스 가로채기
var Program = oop.class({
	run: function()       { console.log("run Program.", msg); },
	terminate: function() { console.log("Terminated the Program.") }
});

// *** HERE ***
// Pass class instance arguments
var p = new Program();
oop.interception( p, oop.behaviors.LoggingBehavior );

// Call a 'run' method.
p.run("Now running...");
p.terminate();

// Output
------ enter interception ------
[Thu Nov 13 2014 09:29:41 GMT+0900 (KST)]  {}
run Program.  Now running...
Terminated the Program.
------ end interception ------
  • 사용자 정의 가로채기 (Behaviors)

    • 사용자 정의 가로채기 정의

가로채기 행위를 사용자 정의로 만드시려면 oop.interceptionBehavior 메서드를 호출합니다.

var customBehavior = oop.interceptionBehavior(
	function() { console.log("before"); },
	function() { console.log("after"); },
	function() { console.log("throw exception"); },
	function() { console.log("finally"); }
);

var Program = oop.class({
	run: function() { console.log("run Program."); }
});

var p = new Program();
oop.interception(p,  customBehavior);
p.run();

// Output
before
run Program.
after
finally

코드가 실행 중 예외가 발생할 경우 다음 처럼 exception 함수가 실행됩니다.

var Program = oop.class({
	run: function() { 
		console.log("run Program."); 
		throw "crashing... "; 
}});

var p = new Program();
oop.interception(p,  customBehavior);
p.run();

// Output
before
run Program.
throw exception crashing...   // HERE exception behavior.
finally


Posted by 땡초 POWERUMC

댓글을 달아 주세요

필자 만든 소스 코드가 GitHub에 올린 것들이 20여 가지가 넘어간다.
소스 코드도 중요 하지만 이것을 잘 설명하는 것도 무척 중요한 것 같다. 거기에 예쁘게 꾸밀 수 있다면 이건 신이 주신 능력임이 분명할 거다. ㅠ

Markdown ToC (Table of Contents)

이런 어려움에 착안하여 Markdown ToC를 만들어 GitHub에 공개했다.
링크 : https://github.com/powerumc/markdown-toc

Markdown ToC는 Markdown 문법을 이용하여 만든 문서에 목차를 만들어 주는 라이브러리이다. 진짜 별 거는 아니고, 필자가 필요해서 쓱~ 만들었다.

MIT 라이센스로 공개 했으며, 이미 잘 만들어진 marked.js, tocify.js 라이브러리를 조합하여 간단하게 만들어 보았다.

디자인이나 기능을 추가 하신 분은 Pull Request 올려 주세요.

아래는 Markdown Toc로 만들어 본 필자 저장소의 gh-pages 웹 페이지이다. (현재 모바일 미 지원)

Features

사소하지만 몇 가지 특징이 있다.

  1. Markdown ToC 코드를 받고 원하는 곳에 올리기만 하면 된다. (gh-pages 브랜치 등)
  2. 브라우저에서 실시간으로 Markdown 파일을 랜더링한다.
  3. README.md 파일만 수정하고 로컬 컴파일이 필요 없다.
  4. Jekyll, Assemble 등 템플릿 문법을 익힐 필요가 없다.
  5. 심플하다.

How to - Beginner

1. 소스 코드 다운로드

필자의 GitHub 저장소에서 master.zip 파일을 다운로드 받고, 풀면 된다.

2. 올리고 싶은 곳에 올린다

올리고 싶은 곳에 올리면 된다.

How to - Pro Git

1.다음과 같이 Markdown ToC 를 clone 한다.

$ git remote add markdown-toc https://github.com/powerumc/markdown-toc.git  

2.GitHub에서 웹 페이지를 호스팅 할 수 있는 gh-pages 브랜치를 생성하고, Markdown ToC 소스 코드를 받는다.

$ git checkout --orphan gh-pages  
$ git rm -rf .  
$ git commit -am "remove all file for gh-pages"  
$ git pull markdown-toc master:gh-pages  

3. 콘텐트 수정 또는 생성

README.md 파일에 원하는 콘텐트로 채운 후에 커밋을 하면 된다.

$ git commit -am "init commit."  

만약 다른 브랜치에 이미 만들어 놓은 README.md 파일이 있으면 gh-pages 브랜치로 가져오면 된다.

$ git checkout master -- README.md  
$ git commit  

3. GitHub 에 Push 한다.

$ git push origin gh-pages  
Posted by 땡초 POWERUMC

댓글을 달아 주세요

지난 2013년 7월부터 MonoDevelop 공식 프로젝트를 Fork 하여 MonoDevelop Korean 프로젝트를 진행 하였습니다.

그 결과 한 달을 매달려 약 4,500여 문장을 번역하였습니다.
그냥 번역 작업만 하면 쉽게 생각하겠지만, IDE 툴에서 보여주는 메시지를 영문으로 보여야 할지, 한글로 보여야 할지… 여러 문장이 합쳐지면 어색해 지지 않는지… 그리고 직역을 하게 되면 의미가 잘못 전달되지 않는지… 번역에 따른 크래시 버그…. 이런 작업을 일일이 확인 하다보니 한 달이라는 시간이 지났던 것이죠;;;

앞으로 이 사이트를 통해 지속적으로 한글 번역과 개선 작업을 진행 할 예정입니다.

http://monodevelop.co.kr

Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 컴포지트 2014.05.13 09:40 Address Modify/Delete Reply

    노고에 감사드립니다.

  2. 붉은용기병 2014.05.15 11:32 Address Modify/Delete Reply

    와...우....

    감사합니다.




  3. 테릿 2014.09.19 05:12 Address Modify/Delete Reply

    우분투용은 언제 나오나요 -0-;

    무척이나 기다리고 있답니다~~~

  4. 테릿 2014.09.19 05:12 Address Modify/Delete Reply

    우분투용은 언제 나오나요 -0-;

    무척이나 기다리고 있답니다~~~

  5. 도라킹 2015.01.19 13:43 Address Modify/Delete Reply

    윈도우는 언제 나오나요... --;

DeskBoard 앱은 프레젠테이션 등으로 발표를 자주 하는 분들을 위해 필자가 만든 앱입니다. (지난 블로그 글)

이번에 $9.99의 앱 가격을 이달 4월 말까지 $2.99 로 할인합니다.

DeskBoard 앱은 유료/무료 버전 두 가지가 있습니다.
무료 버전도 모든 기능을 지원 하지만 멀티 모니터(두 대 이상 모니터)를 지원하지 않습니다.
그러므로 외부 모니터에 연결하거나 멀티 모니터 지원이 필요한 분만 유료 버전을 구매하시면 됩니다.

자세한 사항은 아래의 AppStore 아이콘을 클릭하면 됩니다.

DeskBoard (유료 $2.99 <- $9.99)
DeskBoard Free (무료)

[동영상] DeskBoard 앱을 사용하는 예

이하 앱에 대한 설명입니다.


여러분의 성공적인 발표나 세미나를 위해 당신에게 더 집중할 수 있도록 DeskBoard 앱을 사용해 보세요.
여러분이 전달하고자 하는 메시지를 다양한 도형을 사용하여 청중들에게 정확하게 전달할 수 있어요.
그럼 청중들은 당신이 무엇을 강조하는지 쉽게 알 수 있답니다.
DeskBoard 앱은 다음과 같은 분들이 사용하는 것을 권장합니다. ^_^

  1. 여러 사람 앞에 발표할 기회가 많은 분
  2. 맥을 프로젝터나 원격으로 공유하여 회의 하시는 분
  3. 강의를 하거나 직업을 가지신 분
  4. 개발자, 프로그래머 중 라이브 코딩을 해야 하는 분


Posted by 땡초 POWERUMC

댓글을 달아 주세요

맥 앱스토어 다운로드

DeskBoard (유료)
DeskBoard Free (무료)

프레젠테이션 앱 - DeskBoard

여러분의 성공적인 발표나 세미나를 위해 당신에게 더 집중할 수 있도록 DeskBoard 앱을 사용해 보세요.

여러분이 전달하고자 하는 메시지를 다양한 도형을 사용하여 청중들에게 정확하게 전달할 수 있어요.
그럼 청중들은 당신이 무엇을 강조하는지 쉽게 알 수 있답니다.

DeskBoard 앱은 다음과 같은 분들이 사용하는 것을 권장합니다. ^_^

1. 여러 사람 앞에 발표할 기회가 많은 분

프로는 항상 발표할 준비가 되어 있다고 해요. 발표할 때 필요한 것 중 하나가 바로 레이저 포인터랍니다.
레이저 포인터도 좋지만, 화면 측면에서 손으로 짚어서 강조하는 것이 감성적으로 더 좋다고 해요.

레이저 포인터를 매번 잊지 않고 준비하기 힘들거나,
직접 화면 측면에서 손으로 짚어서 강조하기 힘든 큰 발표장이라면…

이 앱을 사용하여 청중들을 당신에게 사로잡게 해줍니다.

2. 맥을 프로젝터나 원격으로 공유하여 회의 하시는 분

매우 작은 규모에서는 레이저 포인터가 오히려 방해가 돼요.
특히 레이저 포인터를 사용할 수 없는 원격 회의에서는 레이저 포인터가 아무 소용이 없답니다.

그렇다면 꼭 이 앱을 사용해 보세요.

여러분의 맥 화면을 공유할 때 그냥 선, 화살표 등의 도형을 이용하여 그리면 되니까요.

3. 강의를 하거나 직업을 가지신 분

레이저 포인터를 쓰는 분들은 정확하게 화면을 조준하지 못해요.
수전증이 있는 것이 아닌 줄 알지만, 화면에 쏘는 레이저의 포인트는 부들 부들 떨린답니다.
그래서 청중의 시선이 레이저 포인트를 따라가다 보면 어질 어질할 거에요.

이 앱을 사용하면 수전증 오해를 받지 않고, 화면에 조준한 곳을 정확하게 그려서 가리킬 수 있어요.

4. 개발자, 프로그래머 중 라이브 코딩을 해야 하는 분

개발자, 프로그래머가 강의나 세미나 발표를 한다면, 이 앱이 한층 여러분의 코드를 빛내 줄 거에요.
이 앱을 사용하면 복잡한 코드 위에 도형을 이용하여 강조할 수 있어요.

코드를 콕콕 찝어주면 청중들이 쉽게 집중할 수 있거든요.

특히 라이브 코딩이라면 더 큰 효과를 볼 수 있답니다.

DeskBoard 앱은 다음의 기능을 제공합니다.

  • 다양한 도형 지원
  • 멀티 모니터 지원
  • 풀스크린 모드에서 그리기 지원 (OSX 매버릭스 부터 지원)
  • 도형의 색상, 굵기, 투명도 등을 다양하게 커스터마이징

스크린샷


Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 길냥이 2016.02.24 13:04 Address Modify/Delete Reply

    매우 유용하고 괜찮은 프로그램이네요..
    근데 그린 도형이나 줄, 화살표를 지울수가 없어요... 어떻게 하면 되나요?
    환경설정에 단축키지정해서 그리기, 지우기 모드를 설정하는건 알겠는데
    아무리 해도 안먹힙니다

맥 앱스토어 다운로드

슈퍼 눈팅 (무료)

슈퍼 눈팅 (무료)

눈치 보지 말고 눈으로 팅하자… 눈팅!!

소셜 네트워킹을 하고 있는데 눈치 보인다면…
인터넷 쇼핑을 하고 있는데 눈치 보인다면…

이제 눈팅 하세요… 눈팅 ^_^

주요 기능

  • 인기 있는 웹사이트 목록
  • 투명도를 조절할 수 있음
  • 아이폰, 아이패드, 랩탑 중 원하는 디바이스 모드로 브라우징

v1.1

  • 페이스북, 트위터 등 공유 기능
  • 브라우저 캐시 및 쿠키 제거 기능
  • 소소한 버그 수정

스크린샷

Posted by 땡초 POWERUMC

댓글을 달아 주세요

MonoDevelop 한글판이 곧 업데이트 됩니다.

다운로드 : http://monodevelop.co.kr

MonoDevelop 통합 개발툴의 한글화를 위해 Github에 Pull Request로 게시하였고, 몇 일 후 특별한 문제 없이 MonoDevelop Master 브랜치에 병합이 완료 되었습니다.

[Ide] Translate to Korean language

차후 공식적인 배포에 의해 Xamarin Studio, MonoDevelop, MonoDevelop for Unity 와 같은 개발툴에서 한글 버전을 만나뵐 수 있을 것 같네요.

GitHub MonoDevelop Korean Repository

오탈자 및 버그 신고

Xamarin의 공식적인 버그 신고는 https://bugzilla.xamarin.com/ 에서 신고할 수 있습니다. 다만, 한글 번역과 관련된 버그를 처리해 줄지 모르겠네요.

  1. http://monodevelop.co.kr/ 에서 신고해 주시거나

    또는

  2. GitHub MonoDevelop Korean Repository 에 신고해 주시거나

    또는

  3. 직접 MonoDevelop Repository 에서 Fork 하셔서 작업하시면 됩니다.


Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 컴포지트 2013.08.05 09:09 Address Modify/Delete Reply

    군말없이 merge 시켜주다니..ㅋㅋ
    노고에 감사드립니다.

  2. hellojin 2014.02.11 17:33 Address Modify/Delete Reply

    맥용 xamarin studio 를 사용하려하는데. 한글을 입력하면. 그냥 죽어버리는 군요.. 그래서. 한글화 된걸 사용해보고 싶은데.. 어떻게 해야되는지 통 감이 안오네요.. 어떻게 해야되는지 좀 알려주세요..~ 부탁드립니다.

    • 땡초 POWERUMC 2014.02.12 09:23 신고 Address Modify/Delete

      오 그래요?
      저는 같은 맥에서 죽지 않고 잘 써지는데요...

      기본 내장 외 한글 입력기를 쓴다거나 다른 이유가 있을 것 같은데,
      덤프를 떠주시면 제가 한번 봐 드리겠습니다.

  3. oiziee 2014.03.07 18:07 Address Modify/Delete Reply

    안녕하세요 위에 링크가 죽어있네요
    한글버전을 꼭 구하고 싶은데
    한글버전을 보내주실수 있으신가요?
    부탁드립니다
    pijunyel@naver.com

    • 땡초 POWERUMC 2014.03.07 18:24 신고 Address Modify/Delete

      한글버전은 Xamarin Studio에 함께 배포 되고 있습니다.
      아래의 링크에서 받으시고,
      환경 설정의 Language에 'Korean' 으로 변경해 주시면 됩니다.

      http://xamarin.com/download

  4. 지나가던이 2014.08.05 10:24 Address Modify/Delete Reply

    한글 버전 주석은 너무나도 감사드립니다.
    하지만, 버그가 있더군요... 조금 아쉽습니다.

    '아'를 입력할경우 '아'를 입력한 후에도 한번 더 무언가를 입력해주어야만 해결되는 현상이 있습니다.

    더 좋은 버전 기대하겠습니다.

  5. TeemoSoft 2015.01.07 01:37 신고 Address Modify/Delete Reply

    안녕하세요 맥에서 유니티 모노디벨롭 을 사용중인데 http://monodevelop.co.kr에서 받아서 사용해보니
    Assembly-UnityScript 로드 실패
    Assembly-UnityScript-firstpass 로드 실패

    이렇게 뜨네요 작업하는데는 큰 문제는 없지만 어딜 고치면 될까요?

MonoDevelop for Korean version..!

MonoDevelop은 ECMA 표준을 가장 완벽하게 구현한 Mono 플랫폼을 개발하기 위한 통합 개발 도구 입니다.

2011년경, Xamarin 기업에 인수합병 되면서 모바일에 강력하게 대응되는 플랫폼으로 한 단계 진화하였습니다. iOS, Android 외에 콘솔 게임 개발도 지원하게 되었습니다.

https://github.com/powerumc/monodevelop_korean

현재 진행 사항입니다.

  • POSIX에서 재정한 Gettext API에 대응되는 .po 한글화 작업이 거의 완료가 되었습니다.
  • 한글을 지원하기 위해 MonoDevelop 내부 코드가 변경되었습니다.
  • 한글화에 따른 알 수 없는 크래시가 발생하여 디버깅 중입니다.
  • 다음 주 중으로 안정성 테스트 및 한글화 품질 테스트를 진행할 예정입니다.
  • 테스트 이후 공식적인 배포 사이트를 개설할 예정이며,
  • Mono Community 에 제출될 예정입니다.

많은 응원과 기대 부탁 합니다.

진행중인 MonoDevelop (Xamarin Studio) 스크린 샷




Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 김영환 2013.07.25 14:54 Address Modify/Delete Reply

    앗!!!!

    감사합니다.
    화이팅!!!

  2. 컴포지트 2013.07.25 17:01 Address Modify/Delete Reply

    일본어와 중국어 번역은 이미 끝났는데 오늘 한글화 소식을 들으니 이런 꿀같은 소식이!
    정말 감사합니다.

    근데 이툴이 한글 깨져요. 맥이나 리눅스나 둘다 한글 깨져요..
    이건 어떻게 해결 됐나요?

  3. 컴포지트 2013.07.26 18:19 Address Modify/Delete Reply

    인코딩 어떻게 지정하던 한글 입력이 안됩니다. 출력도 문제고 입력조차 어려운 실정입니다. 아예 이스케이프 해야지 됩니다..

    • 엄준일 2013.07.27 00:24 Address Modify/Delete

      한글 입력이 깨진다는게
      입력할 때 'ㅎㅏㄴㄱㅡㄹ' 이렇게 입력 되는 것을 말씀하시는 거죠?

  4. kmshts 2013.07.31 01:06 Address Modify/Delete Reply

    저도 이파일을 받아봤음좋겠는데 어디서 받아볼수있습니까? po파일만

    • 엄준일 2013.07.31 04:19 Address Modify/Delete

      Github에서 monodevelop_korean 브랜치에 있습니다.
      https://github.com/powerumc/monodevelop_korean/tree/monodevelop_korean

      위의 링크 파일 4개 중에 하나예요.

JS-Lambda 자바스크립트 라이브러리를 공개합니다.


JavaScript Array Extensions 자바스크립트 오픈 소스를 개발한 데 이어 JS-LambdaLGPL 라이센스로 공개합니다.

JavaScript 에서 람다 표현식(Lambda Expression)을 사용할 수 있도록 만든 라이브러리 입니다. 자세한 내용은 아래의 소스 코드를 참고 하시면 됩니다.

Github: https://github.com/powerumc/js-lambda

JS Lambda

  • It is possible lambda expression that can be used JavaScript.
  • you just got a function F();

Simple Examples

// Before  
function func(a,b) {
    return a + b;
}  
console.info( func(4,6) );


// ** After with JS-Lambda **  
var func = F("a,b => a + b");  
console.info( func(4,6) );  

// Result  
10

Or you can invoke directly

// Before  
function anonymousMethod(a,b) {
    return a + b;
}  
console.info( anonymousMethod(4,6) );  

// ** After with JS-Lambda **  
console.info( F("a,b => a + b")(4,6) );  

// Result  
10

Callback Examples

// Before  
function callback( func ) {
    if( func ) func();
}  

callback( function() { console.info('My name is Junil Um'); } );  

// ** After with JS-Lambda **  
callback(  F("() => console.info('My name is Junil Um');")  );  

// Result  
My name is Junil Um  

With jQuery

// Before  
var li = $("item li");  

li.each( function(i, o) {
    $(o).addClass("some");
} );


// ** After with JS-Lambda **  
var li = $("item li");  

li.each( F("(i, o) => $(o).addClass('some');") );  


Posted by 땡초 POWERUMC

댓글을 달아 주세요

VSGesture for Visual Studio 2013 Preview 배포 완료

Visual Studio 2013 Preview 버전 배포 완료

기능적으로 향상된 것은 없습니다. 이번 버전의 Visual Studio 2013의 Extension Schema가 골때리게 바껴서 ;;

Visual Studio 2013의 Tools -> Extension Manager 에서 다운로드 받으실 수 있습니다. (검색: vsgesture)

Download : http://visualstudiogallery.msdn.microsoft.com/e03c91ff-e20d–4dcc–822b–172a68c40f5b

  • Version 12.0 [2013/07/17]
    Support Visual Studio 2013 Preview

  • Version 11.11 [2012/03/01]
    Modified wrong display texts.

  • Version 11.1
    Resolved compativility bug between VS2012 and VS2010.

  • Version 11.0
    Support Visual Studio 2012, 2010

VSGesture shipped for Github. https://github.com/powerumc/vsgesture
VSGesture for VS2012, VS2010 is now available for download.
http://blog.powerumc.kr/305

VSGesture can execute command via mouse gestures within Visual Studio.
If you have any feedback, please send me an email to powerumc at gmail.com.

Visual Studio 2005, 2008 version : http://visualstudiogallery.msdn.microsoft.com/en-us/F5007932–0720–492B–8A51–631D5265F6B7




Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 설치가 안됩니다 2013.09.04 22:37 Address Modify/Delete Reply

    안녕하세요
    확장 관리자를 통해서 다운 받을려고 하는데,
    종속성 경고 - 다음 참조가 있어야 설치를 계속 할 수 있습니다. - Visual studio MPF 라는 팝업창이 뜨면서 설치가 안됩니다. 이거 어떻게 해야 하나요?

    참고로 윈도우7 64bit, visual studio 2010사용하고 있습니다.

jQuery 1.7.1 버그 패치를 공유합니다.

jQuery 1.7.1 의 정식 버전은 인터넷 익스플로러(IE; Internet Explorer) 10 버전에서 런타임 버그가 존재한다. 이 버그는 jQuery 1.7.1 내부적으로, 그리고 jQuery UI 에 영향을 미친다.

그러므로 현재 jQuery 1.7.1 버전을 사용하는 버전에서는 필자가 공유한 코드를 사용하거나 패치 방법으로 코드를 수정하면 된다.


다운로드 및 추가정보






Posted by 땡초 POWERUMC

댓글을 달아 주세요

Javascript Array Extensions

Array Extensions는 Node.js 와 브라우저에서 사용할 수 있는 배열 라이브러리이다.

요즘 자바스크립트(JavaScript) 를 만지는 날이 많아져서 JavaScript 로 뭘 만들 수 있을까 하는 생각에 기억을 더듬어 보니 JavaScript 에서 배열을 다루는 일이 많았다. jQuery의 selector 등으로 DOM을 다루는데 효과적이지만, 배열을 다룰 때는 모라는 점이 많았다.

인터넷에 찾아보면 자바스크립트(JavaScript)로 배열을 다루는 오픈 소스를 발견하였다. 그 중 가장 호감이 가는 자바스크립트(JavaScript) 오픈 소스를 발견하였다. 자바스크립트로 C#과 가장 비슷하게 Enumerable과 LINQ를 구현한 자바스크립트다.

사실, 필자가 만들고 싶었던 디자인이 linq.js와 비슷했지만, 역시나 이미 나와있으므로 좀 더 Lightweight 하게 쓰도록 만들어 보았다. 요 몇일 3~4일 동안 틈틈히 만들었고, 더 큰 디자인으로 갈 생각은 없다.

완성도를 좀 더 높이면 npm, nuget 등에서 패키지로 배포할 예정이다.

설치하기

Nuget

PM> Install-Package JS.Array.Extensions

Node.JS

$ npm install js-array-extensions

required('js-array-extensions');

from Github

Array Extensions는 Github를 통해 배포하고 있다.

https://github.com/powerumc/array-extensions

git 를 이용하여 다음과 같이 소스 코드를 받을 수 있다. 소스 코드를 받을 디렉토리로 이동한 후 다음의 명령을 실행하면 된다.

git init  
git clone https://github.com/powerumc/array-extensions.git  

사용 방법은 매우 간단하다. README.md 에 포함한 예제 하나만 보면 쉽게 이해할 수 있을 거라 생각한다.

var arr = Array.range(1, 10)
               .select(function(i) { return { number:i, name:"POWERUMC " + i } })
               .where(function(o) { return o.number >= 5 })
               .take(3);  

// results var arr  
POWERUMC 5  
POWERUMC 6  
POWERUMC 7  

현재까지 지원하는 Array Methods 는 십여가지가 넘지만 부족한 것 같아서 좀 더 보강할 계획이다. 함께 코드를 개선하실 분은 Fork 하셔서 작업 후에 저에게 알려주시면 됩니다.

  • any
  • first
  • firstOrDefault
  • firstOrNew
  • last
  • lastOrDefault
  • lastOrNew
  • where
  • select
  • foreach
  • orderBy
  • take
  • skip
  • sum
  • average
  • range and Array.range
  • union
  • clone

image-1

Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 황정현 2013.06.17 17:51 Address Modify/Delete Reply

    자바스크립트 학습용으로도 좋네요. ^^

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

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

댓글을 달아 주세요

TV 프로에서 어떤 조사를 통해 재미있는 사실이 밝혀졌습니다.

페이스북 오래 하는 직원, 업무성과 더 높아

회사에서 페이스북... 대놓고 하기에도 그렇고, 숨어서 하기에도 그렇고...



맥에서 즐겨 사용하는 페이스북 알리미 프로그램이 Shareware로 자꾸 돈내라고 팝업이 뜬다.
$2.99 짜리 맥OS 앱인데, 결제를 하려다가 주말을 이용해 그냥 만들어 보기로 했습니다.

 

아직 초라한 0.1 버전이므로 감안하고 사용하길 바랄뿐입니다. ^^;
차후 업그레이드를 해야 하는 사명감이 좀 더 생기면 버전업을 할 예정입니다.

(Mac OS, Linux 배포 패키지가 완성되면 다운로드 링크에 추가하겠슴돠)


 

 

  Facebook Tray v0.1 

 

다운로드 링크 (SkyDrive)

https://skydrive.live.com/redir?resid=8B8DDD0D9FFC25E1!5800&authkey=!APgYk8Dtt5YV3r4

 

스크린 샷

 

 

지원 운영체제

  • Windows
  • Mac OS
  • Linux

 

특징

  • 트레이 아이콘에서 페이스북의 새로운 알람 개수 표시
  • 네트워크를 통한 페이스북 API 없이 실시간 알람
  • 모바일 화면의 페이스북 윈도우 제공
  • 외부 링크는 데스크탑 브라우저와 연결
  • 내부 링크는 FacebookTray 내부 브라우저와 연결
  • 여러 운영체제 지원


실행 방법

  • 윈도우
    기본 설치 경로인 윈도우 데스크탑에 FacebookTray 폴더의 FacebookTray.exe 를 실행
  • 맥 OS
    기본 설치 경로인 /Applications (응용프로그램)에서 FacebookTray.app 을 실행
  • 리눅스


설치되는 컴포넌트

  • 실행 파일
  • Qt Runtime (Qt Core/OpenGL/WebKit)
  • C++ 10.0 재배포(Redistributable) 패키지 (설치 안됨)
  • OpenSSL (설치 안됨)


Posted by 땡초 POWERUMC

댓글을 달아 주세요

Visual Studio 2005버전부터 만들어온 VSGesture 확장 도구가 Visual Studio 2008, Visual Studio 2010, 그리고 Visual Studio 11버전까지 나왔습니다. VSGesture는 Visual Studio에서 마우스 오른쪽 버튼을 이용하여 제스쳐를 하면 여러 가지 동작을 하는 확장 도구 입니다.

   

   

   

현재 이 확장 도구는 이미 오픈 소스로 공개를 하였답니다.

http://vsgesture.codeplex.com

   

그 밖에 오픈 소스로 공개한 다른 것들도 구경해 보시고요.

Umc.Core Framework http://umccore.codeplex.com/

jQuery DateTimePicker http://umcdatetimepicker.codeplex.com/

MEFGeneric http://mefgeneric.codeplex.com/

vutpp for VS2010 http://vutpp.codeplex.com/

   

기타 무료 확장 도구 및 Visual Studio 백서

http://www.powerumc.kr/ko-kr/products.aspx

   

   

웹을 통해 이 버전을 다운로드 받으려면 다음의 링크를 참고하세요.

Visual Studio 11, 2010 - http://visualstudiogallery.msdn.microsoft.com/e03c91ff-e20d-4dcc-822b-172a68c40f5b

Visual Studio 2005, 2008 - http://visualstudiogallery.msdn.microsoft.com/F5007932-0720-492B-8A51-631D5265F6B7

   

   

Visual Studio 2010, 11 에서는 Tools(도구) -> Extension Manager(확장 관리자)를 이용하여 바로 설치할 수 있습니다.

   



Posted by 땡초 POWERUMC

댓글을 달아 주세요

과거 Prototype, Dojo 와 같은 자바스크립트 라이브러리가 많았었지만, jQuery 의 매력 있는 확장 가능성으로 이미 대세를 이끌어가고 있는 대표적인 자바스크립트 라이브러리이죠. 그 중에서도 많은 jQuery UI 라이브러리를 제공하고 있는데, DateTimePicker 는 제 구미에 맞게 확장하여 오픈 소스로 공개하였습니다.
 

소스 코드도 그다지 볼 것은 없지만, 필요한 분이 있으시면 사용해보시고 피드백도 주시면 좋을 것 같습니다.   

http://umcdatetimepicker.codeplex.com/

   

umc DateTimePicker

외국에서 공개된 DateTimePicker

   

그 외에 피드백이나 질문은 새로 오픈한 사이트, 여기에 남겨주세요

http://www.powerumc.kr/ko-kr/supportforums.aspx

   

   

사용 방법은 간단합니다.

// 스크립트 초기화

<link type="text/css" href="css/jquery.ui.theme.css" rel="stylesheet" />
<link type="text/css" href="css/jquery.ui.datepicker.css" rel="stylesheet" />
<link type="text/css" href="css/demos.css" rel="stylesheet" />
<script type="text/javascript" src="js/jquery-1.7.1.js"></script>
<script type="text/javascript" src="js/jquery.ui.core.js"></script>
<script type="text/javascript" src="js/jquery.ui.widget.js"></script>
<script type="text/javascript" src="js/jquery.ui.datepicker.js"></script>
   

// umcDateTimePicker 스크립트 소스 추가
 
<script type="text/javascript" src="jsDateTimePickerV1/DateTimePicker.js"></script> 

   

// 스크립트 블록
<script type="text/javascript">

  $(function () {
    
$("#datetimepicker").datetimepicker();
  
});

</script>

 
// HTML 블록
 
<input id="datetimepicker" type="text" />

   

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

jQuery DateTimePicker 오픈 소스 공개  (0) 2012.02.12
Posted by 땡초 POWERUMC

댓글을 달아 주세요

VSGesture shipped for codeplex. http://vsgesture.codeplex.com/

VSGesture v2.0 for VS2010 is now available for download.
http://blog.powerumc.kr/305
http://visualstudiogallery.msdn.microsoft.com/en-us/e03c91ff-e20d-4dcc-822b-172a68c40f5b


VSGesture can execute command via mouse gestures within Visual Studio2010.
If you have any feedback, please send me an email to powerumc at gmail.com.

Visual Studio 2005, 2008 version : Here

   

   

Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. Ted 2010.05.23 17:06 Address Modify/Delete Reply

    정말 유용합니다 ;)
    언제 이런걸 만드셨는지! 잘쓸께요!

  2. 양재우 2010.07.01 00:07 Address Modify/Delete Reply

    서핑하다 알게 되었습니다. 멋집니다! 편하게 개발할 수 있겠어요 ^^;

  3. 작은개발자 2011.05.11 14:49 Address Modify/Delete Reply

    완전 감사합니다 ㅜ.ㅜ; 완전 편하고 좋아요~~~

    나중에 2010 이후 버전 나와도 꼭 만들어 주세요~~~

    모델링 문서도 너무 잘 보고 있습니다. ^^

 

지난 6월 10일 VSTS 2010 팀에서 진행한 MEF(Managed Extensibility Framework) 세미나에서 보여드린 데모를 조금 수정하여 Visual Studio Gallery 에 공개하였습니다.

Visual Studio 2010 이 WPF 기반의 IDE 환경으로 탈바꿈하면서 특히 코드 에디터 쪽은 WPF 의 기능을 유감없이 보여주었습니다. 특히 코드 에디터는 MEF 를 통해 대부분의 기능이 만들어졌고, 이것을 확장할 수 있는 기능을 만드는 것이 얼마나 편해졌는지 보여주기 위한 데모였습니다.

세미나에서도 설명했지만 현재 Visual Studio 2008 까지 버전에서 이러한 확장 기능을 개발하기 위해서는 굉장히 많은 단계를 거쳐야 합니다. Visual Studio 2008 까지는 COM 을 기반으로 한 IDE 이기 때문에 적용되는 기술만 나열해도 절대 단순하지 않은 과정을 거쳐야 합니다. 마우스와 키보드와 같은 장치의 이벤트를 핸들링 해야 하고, GDI+ 를 이용해 화면에 드로잉을 하고 잔상과 깜빡임을 없애기 위해 더블 버퍼링 등의 기법이 조합되어야 했습니다. 그리고 나은 사용자 인터페이스를 위해 많은 기교를 부려야만 했죠.

   

멀리서 프레젠테이션을 시청하는 분들도 커서의 위치를 잘 보이도록 화살표가 커서를 따라 다닙니다. 
 

 

Visual Studio Gallery

Umc.Core.Tools.MousePresentationTracker.v1.0

   

   

현재는 단순하게 마우스를 따라다니는 데모를 급 개조했지만, 나중에는 생각해 놓은 기능들을 추가하려고 합니다. 어쨌든 이전에 공개했던 VSGesture 와 다른 컨셉으로 프레젠테이션을 위한 도구로 점차 기능이 추가될 예정입니다.

   

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

MousePresentationTracker.v1.0  (0) 2009.07.17
Posted by 땡초 POWERUMC

댓글을 달아 주세요



알툴바를 아시는지요? 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

댓글을 달아 주세요