[.Net] RSA 암호화

.Net/.Net 2013. 3. 13. 11:03

외부 프로그램과 연동하는 dll을 만들어야 했는데 .h, .lib를 같이 배포했기 때문에 __declspec을 사용했었습니다.

 

다른 방법으로는 모듈 정의 파일을 이용하는 방법도 있습니다.

 

 

 

 

 

프로젝트 속성 -> 구성속성 -> 링커 -> 입력 -> 모듈 정의 파일

posted by 뚱2

링크 : http://blogs.msdn.com/b/eva/archive/2009/03/24/visual-studio-tip-3.aspx 

 

posted by 뚱2

TextBox에 PlaceHolder 기능을 추가해야 해서 이것 저것 해보다가

 

OnPaint로 그릴 생각까지 했는데 분면 OnPaint를 오버라이드 했는데도 이벤트가 발생하지 않았습니다.

그럴때는 서브클래싱한 컨트롤에서 SetStyle을 설정('SetStyle(ControlStyles.userPaint, true)')해줘야 합니다.

 

SetStyle : http://msdn.microsoft.com/ko-kr/library/system.windows.forms.control.setstyle.aspx

 

그런데 구글링으로 찾은 소스중 보다 Win32 API를 이용해서 텍스트박스에 PlaceHolder 기능을 구현한게 있네요.

 

public class CueTextBox : TextBox

{  

    private static class NativeMethods

    {

        private  const uint ECM_FIRST       = 0x1500;

        internal const uint EM_SETCUEBANNER = ECM_FIRST + 1;

        [DllImport("user32.dll", EntryPoint = "SendMessageW")]

        public static extern IntPtr SendMessageW(IntPtr hWnd, UInt32 Msg, IntPtr wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);

    }

    private string _cue;

    [

        Description("PlaceHolder로 사용될 텍스트"),

        Category("Appearance"),

        Browsable(true),

    ]        

    public string Cue

    {

        get

        {

            return _cue;

        }

        set

        {

            _cue = value;

            UpdateCue();

        }

    }

    public CueTextBox()

    {

        this.SetStyle(ControlStyles.UserPaint, false);

        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);

    }

    protected override void OnPaint(PaintEventArgs e)

    {

        base.OnPaint(e);

    }

    private void UpdateCue()

    {

        if (IsHandleCreated && _cue != null)

        {

            NativeMethods.SendMessageW(Handle, NativeMethods.EM_SETCUEBANNER, (IntPtr)1, _cue);

        }

    }

    protected override void OnHandleCreated(EventArgs e)

    {

        base.OnHandleCreated(e);

        UpdateCue();

    }

}


'.Net > WinForm' 카테고리의 다른 글

[.Net] FolderbrowserDialog Custom Action  (0) 2014.02.08
[WinForm] OpenFileDialog  (0) 2013.03.13
posted by 뚱2

[PhotoShop] 이미지 흑백 전환

일반 2013. 2. 22. 11:41

포토샵 정품은 비싸기 때문에 맥 앱스토어에서 싼 Pixelmator를 사용하고 있습니다.


그런데 이게 포토샵과 인터페이스가 거의 흡사합니다.


포토샵 잘하시는 분은 이것 보고 그냥 사용하실 것 같습니다.



Image -> Color Adjustments...



위엣것 중에 마음에 드는 필터를 선택하시면 됩니다.



posted by 뚱2

링크 : http://blog.naver.com/PostView.nhn?blogId=monk773&logNo=90144334661 

'.Net > .Net' 카테고리의 다른 글

[.Net] HTTP POST/WebClient (C#) and CSV formated string  (0) 2013.04.12
[.Net] RSA 암호화  (0) 2013.03.13
[.Net] Castle DynamicProxy Tutorial  (0) 2013.01.23
[.Net] NuGet  (0) 2013.01.23
[.Net] AOP 프로그래밍  (0) 2013.01.23
posted by 뚱2

링크 : http://ffmpeg.org/ffmpeg.html 

 

튜토리얼 : http://dranger.com/ffmpeg/tutorial01.html 

 

위키 : http://ko.wikipedia.org/wiki/FFmpeg

'C/C++ > FFmpeg' 카테고리의 다른 글

[FFmpeg] 동영상의 기본적인 이해  (0) 2013.05.16
[FFmpeg] library document  (0) 2013.05.02
[FFmpeg] thumbnail 추출  (0) 2013.04.29
[FFmpeg] FFMpeg 윈도우 컴파일  (0) 2013.04.28
[FFmpeg] FFmpeg을 이용한 동영상 인코딩  (0) 2013.04.28
posted by 뚱2

이 매킨토시에 관하여를 클릭 합니다.




추가정보를 클릭 합니다.




왼쪽 상단의 서비스를 클릭합니다.




'나의 서비스 및 지원 보증 기간 상태 확인'을 클릭 하시면 웹사이트로 이동하여 보증기간을 확인할수 있습니다.


posted by 뚱2

[JSON.net] Json.Net

.Net/Json.net 2013. 2. 10. 01:22

Homepage: http://james.newtonking.com/projects/json-net.aspx 

Document : http://james.newtonking.com/projects/json/help/

posted by 뚱2

링크 : http://www.cyworld.com/programer1234/9368817 

'.Net > C#' 카테고리의 다른 글

[C#] Linq for xml tutorial  (0) 2013.05.23
[C#] XML Serialize Tutorial  (0) 2013.05.08
[C#] Visual Studio TODO 만들기  (0) 2013.01.30
[C#] Form close와 Dispose  (0) 2013.01.28
[C#] 정적 생성자 (static 멤버 초기화)  (0) 2013.01.15
posted by 뚱2

링크 : http://www.viva64.com/en/b/0169/

 

posted by 뚱2

링크 : http://underclub.tistory.com/800 

다운로드 : http://kkwaks.net/405




KeyRemap4MacBook-8.0.0.dmg


private.rtf


posted by 뚱2

[C#] Visual Studio TODO 만들기

.Net/C# 2013. 1. 30. 13:56

 

 

출력창에 위와같이 출력이 된다.

해당 라인을 더블클릭 하면은

 

 

실제 소스페이지의 라인으로 이동한다.

using System;

namespace KIS.Util
{
    /// <summary>
    /// 디버깅을 도와주는 유틸 클래스
    /// </summary>
    public static class MyDebug
    {
        /// <summary>
        /// 현재까지 스택트레이스를 출력한다.
        /// </summary>
        public static void GetStackTrace()
        {
            System.Diagnostics.Debug.Write(Environment.StackTrace);
        }

        /// <summary>
        /// 콘솔에 스트릴을 출력한다.
        /// </summary>
        /// <param name="format"></param>
        /// <param name="args"></param>
        public static void PrintConsole(string format, params object[] args)
        {
            string msg = string.Format(format, args);
            System.Console.Write(msg);
        }

        /// <summary>
        /// 현재 파일 이름
        /// </summary>
        public static string CurrentFile
        {
            get
            {
                return new System.Diagnostics.StackTrace(true).GetFrame(1).GetFileName();           
            }
        }

        /// <summary>
        /// 현재 파일의 라인번호
        /// </summary>
        public static int CurrentLine
        {
            get
            {
                return new System.Diagnostics.StackTrace(true).GetFrame(1).GetFileLineNumber();
            }
        }


        public static void TODO(string format, params object[] args)
        {
            string file_name    = new System.Diagnostics.StackTrace(true).GetFrame(1).GetFileName();
            int    file_number  = new System.Diagnostics.StackTrace(true).GetFrame(1).GetFileLineNumber();
            string msg  = string.Format(format, args);
            string todo = string.Format("{0}({1}) : {2}", file_name, file_number, msg);
            System.Console.WriteLine(todo);
        }
    }
}

'.Net > C#' 카테고리의 다른 글

[C#] XML Serialize Tutorial  (0) 2013.05.08
[C#] Mutex를 통한 다중 인스턴스 실행방지  (0) 2013.02.08
[C#] Form close와 Dispose  (0) 2013.01.28
[C#] 정적 생성자 (static 멤버 초기화)  (0) 2013.01.15
[C#] Assemble.load  (0) 2013.01.15
posted by 뚱2

[C++] C++11

C/C++/VC++ / MFC 2013. 1. 29. 09:22

링크 : http://ko.wikipedia.org/wiki/C++11 

posted by 뚱2

[C#] Form close와 Dispose

.Net/C# 2013. 1. 28. 20:19

링크 (Form.Dispose) : http://msdn.microsoft.com/ko-kr/library/aw58wzka(v=vs.90).aspx

링크 (Form.Close) : http://msdn.microsoft.com/ko-kr/library/system.windows.forms.form.close(v=vs.90).aspx 


모달리스로 닫을시에는 Form.Close()를 호출

모달로 닫을시에는 Form.DialogResult 프로퍼티에 값을 대입

posted by 뚱2

K교수의 객체지향 이야기

Books 2013. 1. 27. 21:11




1. 제   목 : K교수의 객체지향 이야기
2. 출판사 : 배움터
3. 저   자 : 김태균
4. 가   격 : 24,000원 
5. 난이도 : 초중급 (★★★)

6. 판   매 : 절판
7. 평   가 : ★★★


객체지향 책이 대부분 외국 책이거나 번역책인데 이책은 저자가 국내분이시다. 

그리고 전문서적 같지 않게 글이 위트가 있어 소소한 재미가 있다.

글의 전체적인 내용은

객체지향의 기본설명(추상화, 상속, 다형성, 동적 바인딩)과 함께

각 언어별로 동적 바인딩을 어떻게 처리하는지 설명하고 있다.

책의 전체 내용에 중요한 점 하나는 리팩토링을 추천하는 부분이다.

프로그램을 설계하거나 만드는 사람이 전지적인 통찰력이 있지 않는 이상

한번에 설계를 완벽하게 할수 없으며 클라이언트의 요구사항이 정확하기 않기 때문에

사실상 처음에 설계를 완벽하게 할수 없다.

결국 요구사항 변화에 대처하기 위해서는 리팩토링을 통한 유연한 설계가 필수이다.

책의 중간에 TDD와 비슷한 내용도 있는데 사실 객체지향을 개발하다보면은 TDD는

자연스럽게 사용하게 된다고 할 수 있다.

객체지향을 처음접하는 초보 유저 보다는 언어을 익힌후 한두번의 프로젝트를 해본 사람이

보면 좋을 것 같다.


posted by 뚱2

[XtraGrid] XtraGrid Option

.Net/XtraGrid 2013. 1. 24. 09:32

링크 : http://blog.naver.com/hiphoptrain?Redirect=Log&logNo=130087380966 

'.Net > XtraGrid' 카테고리의 다른 글

[XtraGrid] Online Document  (0) 2012.04.13
[XtraGrid] Copy & Paste 구현  (0) 2012.04.11
[XtraGrid] How to make my grid columns read-only  (0) 2012.04.08
[XtraGrid] Checkbox 구현하기  (1) 2012.04.06
[XtraGrid] Fixed Columns  (0) 2012.04.05
posted by 뚱2

링크 : http://kozmic.net/dynamic-proxy-tutorial/ 

링크 : http://docs.castleproject.org/Tools.DynamicProxy.ashx

 

'.Net > .Net' 카테고리의 다른 글

[.Net] RSA 암호화  (0) 2013.03.13
[.Net] EXE를 포함한 외부 DLL을 같이 배포하기  (0) 2013.02.19
[.Net] NuGet  (0) 2013.01.23
[.Net] AOP 프로그래밍  (0) 2013.01.23
[.Net] CodeDomProvider  (0) 2013.01.15
posted by 뚱2

[.Net] NuGet

.Net/.Net 2013. 1. 23. 14:27

링크 : http://debop.blogspot.kr/2012/03/nuget.html

 

이클립스 보면은 마켓이 있어서 다양한 패키지들을 다운로드 받는다.

 

이거랑 비슷한게 NuGet이라고 Visual Studio 2010 부터 지원한다.

 

 

'.Net > .Net' 카테고리의 다른 글

[.Net] EXE를 포함한 외부 DLL을 같이 배포하기  (0) 2013.02.19
[.Net] Castle DynamicProxy Tutorial  (0) 2013.01.23
[.Net] AOP 프로그래밍  (0) 2013.01.23
[.Net] CodeDomProvider  (0) 2013.01.15
[.Net] Aspect Oriented Programming With .Net  (0) 2013.01.14
posted by 뚱2

[.Net] AOP 프로그래밍

.Net/.Net 2013. 1. 23. 12:20

링크 : http://doc.postsharp.org/postsharp/documentation#getting-started 

링크 : http://msdn.microsoft.com/ko-kr/library/ee650325 

링크 : http://rafi.inha.ac.kr/~wbstory/tc/wbstory/82 

링크 : http://iyou72.tistory.com/20

링크 : http://blog.naver.com/ansysda?Redirect=Log&logNo=10003899076

 

목차

소개 소개
Aspect란 Aspect란
AOP의 장단점 AOP의 장단점
Trace.WriteLine을 넘어서 Trace.WriteLine을 넘어서
Mixin의 배후 구현 Mixin의 배후 구현
동작 위빙(Weaving) 동작 위빙(Weaving)
정리 정리
결론 결론

소개

AOP(Aspect Oriented Programming)는 개발된 지 오래되었지만 최근에야 Microsoft .NET 개발 커뮤니티에서 주목을 받기 시작했습니다. 새로 채택되는 모든 기술이 그렇듯이 기술과 기술의 사용 방법에 대해서는 많은 오해가 발생하기 마련이며 AOP도 예외는 아닙니다. 이 기사와 다음 코드 샘플에서는 AOP의 실제적인 응용 방법과 AOP에서 처리할 수 있는 몇 가지 일반적인 문제를 설명하며 AOP에 대해 집중적으로 다룰 예정입니다. 또한 웹 서비스를 사용하는 응용 프로그램을 살펴보고, AOP 프레임워크를 사용하여 웹 서비스에서 반환하는 개체에 새로운 aspect를 적용함으로써 개체의 기능을 확장해 보겠습니다. 이러한 aspect는 WSDL로 생성된 개체 모델과는 별개로 이 기능만을 위한 것입니다.

Aspect란

개체와 다른 개체 간의 관계를 떠올리면 대개 상속의 관점에서 생각하게 됩니다. 여기서는 Dog라는 추상 클래스를 예로 들어 보겠습니다. 저마다 고유한 동작을 가지는 유사한 클래스를 정의할 때는 대개 상속을 사용하여 기능을 확장하게 됩니다. 예를 들어 Poodle을 정의하는 경우 PoodleDog이므로 PoodleDog를 상속한다고 할 수 있을 것입니다. 지금까지는 괜찮지만 나중에 Obedient Dog라는 이름으로 또 다른 고유한 동작을 정의하면 어떻게 될까요 당연히 모든 Dog가 고분고분한(obedient) 것은 아니므로 Dog 클래스에는 obedience 동작이 포함될 수 없습니다. 또한 Dog에서 상속된 Obedient Dog 클래스를 만드는 경우 Poodle은 이 계층 구조에서 어디에 위치할까요 PoodleDog입니다. 그러나 Poodle고분고분(obedient)하거나 그렇지 않을 수 있습니다. 그렇다면 PoodleDog에서 상속되는 것일까요, 아니면 Obedient Dog에서 상속되는 것일까요 obedience를 Dog 계층 구조에 부적절하게 강제로 적용하는 대신 고분고분한 모든 유형의 Dog에 적용할 aspect로 볼 수도 있습니다.

소 프트웨어 측면에서 볼 때, AOP(Aspect-Oriented Programming)를 사용하면 상속 계층 구조와 별개로 클래스나 개체의 동작을 변경하는 aspect를 적용할 수 있습니다. 그러면 이러한 aspect를 런타임이나 컴파일 시에 적용하게 됩니다. AOP는 설명하는 것보다 예제를 통해 보여 주는 편이 더 간단합니다. 시작하기 전에 반복해서 사용할 네 개의 주요 AOP 용어를 정의해야 합니다.

  • Joinpoint—식별 가능하며 제대로 정의된 코드 지점

  • Pointcut—구성 또는 코드를 사용하여 joinpoint를 지정하는 방법

  • Advice—발생해야 하는 크로스 커팅(Cross Cutting) 작업을 표현하는 방법

  • Mixin—새 동작을 적용할 클래스의 대상 인스턴스와 혼합될 클래스의 인스턴스

이 들 용어에 대한 이해를 돕기 위해 joinpoint를 프로그램의 흐름에 정의된 지점으로 생각해 봅시다. 코드에서 메서드를 호출할 때 해당 호출이 발생하는 지점이 joinpoint의 좋은 예입니다. pointcut을 사용하면 프로그램 흐름을 차단할 joinpoint를 지정하거나 정의할 수 있습니다. 또한 pointcut에는 joinpoint에 도달할 경우 발생하는 advice가 들어 있습니다. 따라서 호출 중인 특정 메서드에 pointcut을 정의하는 경우, 호출이 발생하거나 joinpoint가 호출되면 AOP 프레임워크에 의해 프로그램의 흐름이 중단되고 pointcut의 advice가 실행됩니다. advice는 여러 가지일 수 있지만 호출할 또 다른 메서드로 간주하는 것이 가장 일반적입니다. 그러므로 pointcut이 있는 메서드를 호출하는 경우 실행할 advice는 호출할 또 다른 메서드가 됩니다. 이 advice 또는 호출할 메서드는 메서드가 차단된 개체에 있거나 여기서 혼합한 다른 개체에 있을 수 있습니다. mixin에 대해서는 나중에 좀 더 자세히 설명하겠습니다.

AOP의 장단점

흔히들 AOP를 차단으로 오해하지만 사실은 그렇지 않습니다. AOP는 차단 기능의 힘을 빌어 advice를 적용하거나 동작을 함께 위빙(weaving)할 뿐입니다. 현재 ContextBoundObject를 사용하여 AOP를 연상하게 하는 스타일로 차단하는 방법을 보여 주는 다양한 .NET 코드 샘플을 확인할 수 있습니다. 하지만 이 접근 방식에서는 사전 요구 사항에 따라 차단을 허용해야 하는 모든 클래스가 ContextBoundObject에서 상속되어야 하므로 ContextBoundObject는 이 작업에 적합하지 않습니다. ContextBoundObject 같은 사전 요구 사항이 있는 AOP에 대한 접근 방식은 요구 사항으로 인해 좋지 않은 영향이 발생하므로 복잡한 접근 방식으로 간주될 수 있으며 가능한 한 사용하지 않도록 합니다. 복잡한 접근 방식은 시스템에서 많은 공간을 차지하여 잠재적으로 모든 클래스에 영향을 미치므로 향후 시스템을 변경하거나 수정하는 능력을 떨어뜨릴 수 있습니다.

필자는 Encase라는 간단한 프레임워크를 만들었습니다. 여기서 "간단한"이라는 용어는 시스템 전체에 전혀 영향을 주지 않는다는 의미로 사용한 것입니다. AOP를 사용하면 한 시스템의 서로 다른 부분이 영향을 받게 되지만 간단한 프레임워크를 선택하고 뛰어난 프로그래밍 방식을 적용하면 부정적인 문제를 대부분 완화할 수 있습니다. Encase 프레임워크는 pointcut, mixin 및 aspect 위빙을 단순화하도록 설계되었습니다. 개발자는 대부분의 다른 간단한 AOP 프레임워크에 사용되는 XML 같은 구성 파일 대신 Encase가 있는 코드를 통해 aspect를 적용할 수 있습니다.

AOP가 널리 채택되지 않는 이유로는 복잡한 프레임워크를 꼽을 수 있겠지만, 가장 큰 원인은 현재 사용되고 있는 AOP 예제에서 찾을 수 있습니다. 이들 예제는 거의 모두가 실행 전에 메서드를 차단하고 Trace.WriteLine("Method entered.")을 실행하는 aspect를 적용하도록 구성되어 있습니다. 이러한 일반적인 인식과는 달리 AOP는 로깅, 보안, 계측 등을 제외한 문제를 해결하는 데 유용하게 사용할 수 있습니다.

Trace.WriteLine을 넘어서

AOP에 대한 보다 실제적인 접근 방식을 설명하기 위해 ContactService.Service라 는 웹 서비스에서 사람 개체 컬렉션을 수신하는 응용 프로그램을 만들어 보겠습니다. 현재 .NET 개발에 웹 서비스를 사용하는 가장 일반적인 방법은 XML을 반환하는 웹 서비스를 호출하고 프레임워크에서 자동으로 이 XML을 개체로 deserialize하는 것입니다. 이러한 개체에는 데이터만 있고 동작은 들어 있지 않습니다. .NET Framework 2.0에서는 partial 키워드를 사용하고 동작을 만들어 이러한 자동 코드 생성 개체에 기능을 추가할 수 있습니다. 그러나 다양한 웹 서비스(또는 프록시) 개체에서 일부 특정 동작을 다시 사용하려고 하면 여전히 문제가 발생하게 됩니다. 앞서 언급했듯이 대부분의 경우 공유하는 공통 동작은 추상 클래스에 있고 다른 모든 클래스는 이 클래스에서 상속됩니다. 그러나 웹 서비스 개체를 사용하면 개체에서 기능을 상속할 수 없습니다. 이 문제는 AOP가 얼마나 강력한지 보여 줄 수 있는 좋은 기회로 활용할 수 있습니다.

여기서 소개하는 응용 프로그램의 용도는 연락처 정보를 표시하는 것입니다. 본래는 정보를 표시하는 것이 목적이었지만 이제는 여기에 몇 가지 동작을 추가해야 합니다. 코드 샘플을 살펴보기 위해 TheAgileDeveloper.ContactService라는 가상 디렉터리를 만들어야 합니다. 이 디렉터리는 로컬 시스템에서 TheAgileDeveloper.ContactService 프로젝트가 위치한 폴더를 가리켜야 합니다.

참고 이 프로젝트는 http://localhost/TheAgileDeveloper.ContactService를 통해 액세스할 수 있어야 합니다.

aoparticle01.gif

그림 1. 응용 프로그램 스크린

응용 프로그램에 있는 단일 뷰는 MainForm이라는 WinForm이며, 이 뷰에는 웹 서비스에서 반환된 연락처 개체가 ListView의 왼쪽에 표시됩니다. 연락처를 선택하면 오른쪽에 있는 텍스트 상자에 성과 이름, 그리고 웹 페이지가 표시됩니다. MainForm이 로드되면 ServiceManager 클래스를 호출하여 연락처 정보를 가져옵니다. 다음 ServiceManager 클래스는 언뜻 보면 폼과 웹 서비스 사이의 또 다른 계층을 제외하고는 값을 추가하지 않는 것처럼 보입니다. 그러나 이 클래스는 코드를 복제하지 않고도 웹 서비스에 새 기능을 추가할 수 있는 하나의 공간을 제공하므로 매우 중요한 역할을 수행합니다. 또 다른 이점으로는 전체 응용 프로그램에서 웹 서비스의 자취를 추상화하여 제거한다는 점을 들 수 있습니다.

Public Class ServiceManager
 
    Public Shared Function GetAllContacts() As ContactService.Contact()
        Dim service As ContactService.Service = New ContactService.Service
        Dim contacts() As ContactService.Contact = service.GetAllContacts
        Return contacts
    End Function
 
    Public Shared Sub SaveContact(ByVal contact As ContactService.Contact)
        Dim service As ContactService.Service = New ContactService.Service
        service.SaveContact(contact)
    End Sub
 
End Class

이제 Reference.vb 파일의 TheAgileDeveloper.Client 프로젝트를 살펴보겠습니다. 이 프로젝트는 ContactService의 웹 참조를 가져올 때 wsdl.exe에 의해 만들어진 것입니다. 또한 이 프로젝트는 WSDL에서 다음 Contact 클래스를 자동으로 생성합니다.

'<remarks/>
    <System.Xml.Serialization.XmlTypeAttribute(_
[Namespace]:=http://tempuri.org/TheAgileDeveloper.ContactService/Service1 _ )>  _
    Public Class Contact
 
        '<remarks/>
        Public Id As Integer
 
        '<remarks/>
        Public FirstName As String
 
        '<remarks/>
        Public LastName As String
 
        '<remarks/>
        Public WebSite As String
    End Class

위의 코드에서 현재 Contact 개체는 데이터만 처리합니다. 또한 이 코드는 wsdl.exe에 의해 자동으로 생성되며 다음에 다시 생성하면 모든 변경 내용을 잃어버리게 되므로 편집하지 않습니다. 여기서는 Save라 는 메서드를 호출하여 개체를 저장하는 동작을 소개하겠습니다. 이 동작은 mixin을 사용하여 손쉽게 수행할 수 있습니다. mixin은 인터페이스 구현만 혼합할 수 있는 등의 제한 사항을 제외하면 다중 상속을 연상하게 합니다. 여기서 사용하는 Encase 프레임워크에는 개체를 가져와 래핑하는 Encaser 클래스가 들어 있습니다. 개체를 래핑하면 실제로 새 개체가 만들어지며(이 경우 새 Contact 개체) 여기에는 구성된 mixin과 pointcut이 포함됩니다.

mixin을 만들어 Contact 개체에서 Save 메서드를 호출하려면 인터페이스를 지정해야 하는데, 여기서는 이를 ISavable이라고 하겠습니다. 실제로 개체에 혼합될 것이 바로 이 ISavable 인터페이스입니다. 이 인터페이스는 ContactSave라는 또 다른 새로운 클래스에 구현해야 합니다.

Public Interface ISaveable
    Sub Save()
End Interface
 
Public Class ContactSave
    Implements ISavable
 
    Public Contact As ContactService.Contact
 
    Public Sub Save() Implements ISavable.Save
        ServiceManager.SaveContact(Me.Contact)
    End Sub
 
End Class

이 응용 프로그램에서 Contact 개체에 ContactSave 구현을 혼합하기에 가장 적합한 위치는 ServiceManager입니다. 이 동작을 혼합할 수는 있지만 클라이언트 코드, 즉 MainForm을 변경할 필요는 없습니다. 이는 mixin을 적용한 후에도 ContactContactSave가 통합된 새 Contact 개체가 여전히 본래의 Contact 형식을 유지하기 때문입니다. 다음은 이를 처리할 ServiceManager의 변경된 GetAllContacts 메서드입니다.

 
Public Shared Function GetAllContacts() As ContactService.Contact()
       Dim service As ContactService.Service = New ContactService.Service
       Dim contacts() As ContactService.Contact = service.GetAllContacts
 
       '//각 contact 개체를 래핑합니다.
       For i As Integer = 0 To contacts.Length-1
           '//개체를 래핑하는
     '//encaser의 새 인스턴스를 만듭니다.
           Dim encaser As encaser = New encaser
 
           '//ContactSave의 mixin 인스턴스를 추가합니다.
           Dim saver As ContactSave = New ContactSave
           encaser.AddMixin(saver)
 
           '//Contact 및 ContactSave 구현을 사용하여
     '//새 개체를 만듭니다.
           Dim wrappedObject As Object = encaser.Wrap(contacts(i))
 
           '//새로 래핑된 contact 개체를
     '//이전 contact 개체에 할당합니다.
           contacts(i) = DirectCast(wrappedObject, _
           ContactService.Contact)
           '//래핑된 개체의 형식이 여전히 동일한지 확인합니다.
 
           '//새로 래핑된 Contact 개체를
     '//혼합된 ContactSave의 대상 필드에 할당합니다.
           saver.Target = contacts(i)
        Next
 
        Return contacts
    End Function(참고: 프로그래머 코멘트는 샘플 프로그램 파일에는 영문으로 제공되며 기사에는 설명을 위해 번역문으로 제공됩니다.)

Mixin의 배후 구현

프레임워크에서 pointcut과 advice 또는 aspect를 적용하는 방법은 프레임워크별로 다르지만 적용 목적과 개념은 같습니다. 이 기사에서 Encaser가 개체를 래핑하면 실제로는 System.Reflection.Emit 네임스페이스의 클래스를 사용하여 MSIL 코드를 내보내 즉석에서 새 Contact 형식이 만들어집니다. 새 Contact 형식은 Contact 클래스에서 파생되므로 계속해서 형식을 공유하지만 새로 래핑된 개체에도 여기서 혼합한 ContactSave 개체에 대한 참조가 유지됩니다. ISavable.Save 메서드는 새 Contact 개체에 구현되므로 Save를 호출하면 실제로는 호출을 혼합된 ContactSave 개체에 위임하게 됩니다. 여기서의 이점은 새 Contact 개체를 혼합된 개체에 구현된 모든 인터페이스에 캐스팅할 수 있다는 점입니다.

aoparticle02.gif

그림 2. 래핑된 개체의 UML 다이어그램

.NET Framework 2.0의 부분 클래스 언어 기능을 사용하면 또 다른 partial 클래스에 Save 동작을 추가할 수 있는 것으로 생각할 수도 있습니다. 이는 가능한 일이지만 필자는 코드가 이전 버전의 .NET Framework 1.x와 호환되도록 하기 위해 이러한 방식을 피하고 있습니다. 이제 부분 언어 기능이 있으므로 이전 샘플에서도 일반적인 경우에는 mixin이 필요 없을 것입니다. 하지만 mixin은 개발자가 다른 비관련 개체의 계층 구조에 속한 개체의 다시 사용 가능한 동작을 혼합하도록 하여 partial 클래스보다 더 많은 작업을 수행할 수 있으므로 여전히 중요한 역할을 합니다. partial 키워드를 사용할 때 추가하는 코드는 클래스나 형식이 동일하며 물리적인 위치만 다릅니다. 다음에 소개할 mixin에서는 Contact 클래스에 국한되지 않고 대신 FieldUndoer라는 다시 사용 가능한 클래스인 동작을 추가하는 작업에 대해 설명하겠습니다. FieldUndoerIUndoable 인터페이스를 구현하며 수정된 개체를 원래 상태로 복원할 수 있도록 해 줍니다.

Public Interface IUndoable
        ReadOnly Property HasChanges() As Boolean
        Sub Undo()
        Sub AcceptChanges()
    End Interface

HasChanges 속성은 변경 사항이 발생했음을 나타내며 Undo는 개체를 원래 상태로 되돌리고, AcceptChanges는 개체의 현재 변경 사항을 적용합니다. 따라서 나중에 Undo를 호출하면 마지막으로 변경 사항이 적용된 상태로 복원됩니다. 이 인터페이스가 부분 클래스에 구현된 경우 이 세 개의 메서드는 이 동작을 포함시킬 클래스마다 반복해서 복제되도록 구현되어야 합니다. 필자는 실용주의적인 성향의 프로그래머로 "한 번 코딩하여 한 번만 사용한다"는 원칙을 고수하려 노력하므로 코드를 복제하지 않을 뿐 아니라 복사하여 붙여넣는 경우도 상당히 적습니다. mixin을 사용하면 IUndoable을 구현하는 FieldUndoer 개체를 다시 사용할 수 있습니다. 필자는 이 새로운 기능을 ServiceManager에 다시 혼합하는 방법을 채택하고 있습니다. 모든 클라이언트 코드는 여전히 새로운 mixin을 인식하지 않으며 IUndoable 인터페이스를 사용해야 할 경우가 아니면 변경할 필요도 없습니다. MainFormContact 개체를 변경한 다음 undo를 클릭하여 이 동작을 테스트해 보십시오.

Public Shared Function GetAllContacts() As ContactService.Contact()
        Dim service As ContactService.Service = New ContactService.Service
        Dim contacts() As ContactService.Contact = service.GetAllContacts
 
        '//각 contact 개체를 래핑합니다.
        For i As Integer = 0 To contacts.Length-1
            '//개체를 래핑하는
      '//encaser의 새 인스턴스를 만듭니다.
            Dim encaser As encaser = New encaser
 
            '//ContactSave의 mixin 인스턴스를 추가합니다.
            Dim saver As ContactSave = New ContactSave
            encaser.AddMixin(saver)
 
            '//FieldUndoer의 mixin 인스턴스를 추가합니다.
            Dim undoer As FieldUndoer = New FieldUndoer
            encaser.AddMixin(undoer)
 
            '//Contact 및 ContactSave 구현을 사용하여
      '//새 개체를 만듭니다.
            Dim wrappedObject As Object = encaser.Wrap(contacts(i))
 
            '//새로 래핑된 contact 개체를
      '//이전 contact 개체에 할당합니다.
            contacts(i) = DirectCast(wrappedObject, _
            ContactService.Contact)
            '//래핑된 개체의 형식이 여전히 동일한지 확인합니다.
 
            '//새로 래핑된 Contact 개체를 대상 필드에 할당합니다.
            saver.Target = contacts(i)
            undoer.Target = contacts(i)
        Next
 
        Return contacts
End Function

동작 위빙(Weaving)

mixin은 전체의 작은 부분에 지나지 않습니다. AOP가 진정한 인정을 받는 부분은 혼합된 동작이 함께 위빙될 때 나타납니다. 예를 들어 새 Contact 개체를 사용하는 경우 ISavable.Save 메서드를 호출하면 클라이언트 코드에서는 다음에 IUndoable.Undo를 호출할 때 마지막으로 저장된 변경 내용을 사용하도록 IUndoable.AcceptChanges 메서드를 호출해야 합니다. 이를 검토하여 작은 MainForm에 추가하는 것은 간단하지만 이 규칙을 단일 사용자 인터페이스보다 큰 시스템에 코딩하는 일은 상당한 노력이 요구되는 작업입니다. 이렇게 하려면 Save 메서드가 호출된 모든 항목을 찾은 다음 AcceptChanges를 추가로 호출해야 합니다. 또한 새 코드가 만들어지면 개발자는 Save를 호출할 때마다 이 기능을 잊지 않고 추가해야 합니다. 이는 곧바로 계단식 효과로 이어져 시스템을 순식간에 불안정한 상태로 만들고 추적하기 힘든 다양한 버그를 만들어 낼 수 있습니다. 하지만 AOP(Aspect-Oriented Programming)를 사용하면 이러한 메서드를 함께 위빙할 수 있습니다. 메서드를 위빙하려면 Save 메서드가 호출될 때 Contact 개체가 백그라운드에서 자동으로 AcceptChanges를 호출하도록 pointcut과 advice를 지정합니다.

응용 프로그램에 위빙을 구현하려면 ServiceManager에 코드 한 줄을 추가해야 합니다. 이 코드는 FieldUndoer mixin을 추가한 후에 추가합니다.

'//joinpoint를 저장한 다음 AcceptChanges 메서드를 실행합니다.
encaser.AddPointcut("Save", "AcceptChanges")

AddPointcut 메서드는 서로 다른 여러 개의 서명과 함께 오버로드되어 pointcut을 상당히 자유롭게 지정할 수 있도록 해 줍니다. 호출되는 AddPointcutSave 메서드에 해당하는 문자열을 joinpoint 이름으로, AcceptChanges라는 메서드를 실행할 advice로 사용합니다. 실행을 확인하려면 FieldUndoer.AcceptChanges 메서드와 ContactSave.Save 메서드에 각각 중단점을 설정합니다. MainFormSave 단추를 클릭하면 joinpoint가 차단되어 먼저 AcceptChanges 메서드인 advice를 실행하게 됩니다. advice의 실행이 완료되면 계속해서 Save 메서드를 실행합니다.

이 간단한 예제에서는 전체 응용 프로그램에 걸쳐 새 동작을 추가하는 매우 강력한 기능을 보여 주고 있습니다. AOP는 단순히 기능을 효과적으로 추가하는 방법이 아니라 든든한 조력자의 역할을 담당합니다. AOP는 코드를 다시 사용하고 시스템 관리 용이성을 향상시키는 등의 다양한 이점을 통해 새로운 요구 사항에 발맞추어 손쉽게 발전시켜 나갈 수 있도록 해줍니다. 그러나 이와 동시에 AOP를 잘못 사용하면 시스템 유지 관리에 매우 심각한 영향을 미칠 수 있으므로 AOP의 사용 시기와 방법을 적절히 알아 두는 것이 중요합니다.

정리

AOP 는 아직 대규모 또는 중요한 프로덕션 시스템에 사용할 만큼 발전하지는 못했지만 언어에 대한 지원이 늘어나면 보다 널리 채택될 것으로 예상됩니다. 또한 AOP를 활용하는 소프트웨어 팩토리 같은 새로운 소프트웨어 개발 패러다임은 이러한 지원을 촉진하는 사례로 볼 수 있습니다. 현재 .NET 영역에는 다양한 AOP 프레임워크가 있으며 이들은 각각 고유한 접근 방식과 장단점을 보유하고 있습니다.

  • Encase (영문)— 이 코드 샘플에 포함된 Encase 프레임워크는 AOP를 신속하게 실행하여 AOP의 기반이 되는 개념을 이해하는 수단으로 사용하기 위한 것입니다. Encase는 런타임에 개체에 개별적으로 추가할 수 있는 aspect를 적용합니다.

  • Aspect# (영문)—aspect를 선언 및 구성하는 언어를 기본적으로 제공하는 CLI를 위한 AOP 지원 호환 프레임워크입니다.

  • RAIL (영문)—RAIL 프레임워크는 가상 시스템에서 클래스를 JIT 컴파일 중일 때 aspect를 적용합니다.

  • Spring.NET (영문)—현재 널리 사용되는 Java Spring 프레임워크의 .NET 버전으로 향후 릴리스에 AOP와 함께 구현될 예정입니다.

  • Eos (영문)—C#을 위한 aspect 지향 확장입니다.

결론

이 기사의 목적은 기존의 로깅 또는 보안 예제에 비해 새롭고 보다 실제적인 AOP 적용 방식을 보여 주는 데 있습니다. AOP를 올바르게 사용하면 많은 이점이 있을 뿐 아니라 기존 프로그래밍 옵션으로는 불가능한 결과를 손쉽게 얻을 수 있습니다. 아울러 AOP의 적용 시기와 방법에 대한 결정을 내릴 때는 가능한 한 인터넷에 나와 있는 다양한 리소스를 검색하여 도움을 얻도록 합니다.

저자 소개

Matthew Deiters는 소프트웨어 개발에 깊은 관심을 갖고 있으며 ThoughtWorks에서 컨설턴트로 활동하고 있습니다. 또한 .NET Framework를 사용한 금융 및 보험 업계의 다양한 엔터프라이즈 시스템 개발 업무에 참여했습니다. 그는 XP 프로그래밍과 TTD 방법론을 높이 평가하며 인간이 겪는 문제의 대부분은 디자인 패턴이나 뛰어난 단위 테스트를 통해 해결할 수 있다고 생각하고 있습니다. Matthew의 개인 웹 페이지는 http://www.theagiledeveloper.com/ (영문)입니다.

'.Net > .Net' 카테고리의 다른 글

[.Net] Castle DynamicProxy Tutorial  (0) 2013.01.23
[.Net] NuGet  (0) 2013.01.23
[.Net] CodeDomProvider  (0) 2013.01.15
[.Net] Aspect Oriented Programming With .Net  (0) 2013.01.14
[.Net] 웹 자동화 구현 클래스  (0) 2013.01.09
posted by 뚱2

[Icon] 무료 아이콘

일반 2013. 1. 21. 16:00

링크 : http://www.iconfinder.com/

링크 : http://www.iconarchive.com/

 

posted by 뚱2

링크 : http://isagoksu.com/2009/development/java/creating-custom-annotations-and-making-use-of-them/ 

 

How to Create a Custom Annotations?

There are a lot of documentation about this part in the Internet. All you have to do is basically creating an annotation class like below:

public @interface Copyright {
    String info() default "";
}

And that’s it. Now it’s ready to use! Now you can put copyright information to your classes :) Since we didn’t define any @Target, you can use this annotation anywhere in your classes by default. If you want your annotation to be only available for class-wise or method-wise, you should define @Target annotation. Here is a little table of what options are available:

  • @Target(ElementType.PACKAGE), package header
  • @Target(ElementType.TYPE), class header
  • @Target(ElementType.CONSTRUCTOR), constructor header
  • @Target(ElementType.METHOD), method header
  • @Target(ElementType.FIELD), for class fields only
  • @Target(ElementType.PARAMATER), for method parameters only
  • @Target(ElementType.LOCAL_VARIABLE), for local variables only

If you want your annotation to be available in more than one place, just use array syntax as in:

@Target({ ElementType.PARAMETER, ElementType.LOCAL_VARIABLE })

One thing you may already notice is annotations are interfaces, so you don’t implement anything in them.

How to Make Use of Your Custom Annotations?

Up to here, you can find lots of examples. Okaaay, now let’s do something useful :) For instance, let’s re-implement JUnit’s @Test annotation. As you guys already know, @Test annotation is a marker annotation. Basically it marks the method as test method. If you’re expecting any exceptions, you would set expect attribute in the annotation. You can try anything here, I’m just using this example since everyone knows how @Test annotation works.

First let’s define our annotation:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
    Class expected();
}

You might notice that I used @Retention. This annotation marks our annotation to be retained by JVM at runtime. This will allow us to use Java reflections later on.

Now we need to write our annotation parser class. This class will parse our annotation and trigger some other invocations related to what we want. Keep in mind that if you have more than one custom annotation, then it’s also wise to have separate parsers for each annotation you define. So I’ll create one for this! The basic idea behind the annotation parser is using Java reflections to access the annotation information/attributes etc. So here is an example parser for our @Test annotation:

public class TestAnnotationParser {
    public void parse(Class<?> clazz) throws Exception {
        Method[] methods = clazz.getMethods();
        int pass = 0;
        int fail = 0;

    for (Method method : methods) {
        if (method.isAnnotationPresent(Test.class)) {
            try {
                method.invoke(null);
                pass++;
            } catch (Exception e) {
                fail++;
            }
        }
    }
}

}

That’s all you need. You parser is ready to use too. But wait a minute, we didn’t implement anything about the annotation attributes. This part is a bit tricky. Because you cannot directly access those attributes from the object graph. Luckily invocation helps us here. You can only access these attributes by invoking them. Sometimes you might need to cast the class to the annotation type too. I’m sure you’ll figure out when you see it:) Anyways here is a bit more logic to take our expected attribute into account:

// ...
// this is how you access to the attributes
Test test = method.getAnnotation(Test.class);
// we use Class type here because our attribute type
// is class. If it would be string, you'd use string
Class expected = test.expected();
try {
    method.invoke(null);
    pass++;
} catch (Exception e) {
    if (Exception.class != expected) {
        fail++;
    } else {
        pass++;
    }
}
// ...

Now everything is ready to use. Below example demonstrates how you use Parser with your test classes:

public class Demo {
    public static void main(String [] args) {
        TestAnnotationParser parser = new TestAnnotationParser();
        parser.parse(MyTest.class);
        // you can use also Class.forName 
        // to load from file system directly!
    }
}

Yeah, I hope you enjoyed. Don’t hesitate to put some comments down if you’ve a better approach? Thanks! Here is the full parser class implementation:

public class TestAnnotationParser {
    public void parse(Class<?> clazz) throws Exception {
        Method[] methods = clazz.getMethods();
        int pass = 0;
        int fail = 0;

    for (Method method : methods) {
        if (method.isAnnotationPresent(Test.class)) {
            // this is how you access to the attributes
            Test test = method.getAnnotation(Test.class);
            Class expected = test.expected();
            try {
                method.invoke(null);
                pass++;
            } catch (Exception e) {
                if (Exception.class != expected) {
                    fail++;
                } else {
                    pass++;
                }
            }
        }
    }
}

}

Edit: Also after receiving some emails, I guess I should add a full working example :) So here is one. Just copy paste and run the show :)

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Test {
    String info() default "";
}

class Annotated { @Test(info = "AWESOME") public void foo(String myParam) { System.out.println("This is " + myParam); } }

class TestAnnotationParser { public void parse(Class clazz) throws Exception { Method[] methods = clazz.getMethods();

    for (Method method : methods) {
        if (method.isAnnotationPresent(Test.class)) {
            Test test = method.getAnnotation(Test.class);
            String info = test.info();

            if ("AWESOME".equals(info)) {
                 System.out.println("info is awesome!");
                 // try to invoke the method with param
                 method.invoke(
                    Annotated.class.newInstance(), 
                    info
                 );
            }
        }
    }
}

}

public class Demo { public static void main(String[] args) throws Exception { TestAnnotationParser parser = new TestAnnotationParser(); parser.parse(Annotated.class); } }

'Java > Java' 카테고리의 다른 글

[Java] jar 파일 실행 시키기  (0) 2013.04.07
[Java] JDK Download  (0) 2013.04.02
[Java] Class<?> 의 의미?  (0) 2013.01.21
[Java] JConsole 연결 옵션  (0) 2013.01.05
[Java] Java 모니터링 툴 VisualVM Download  (0) 2012.12.28
posted by 뚱2

[Java] Class<?> 의 의미?

Java/Java 2013. 1. 21. 11:18

링크 : http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html 

 

 

Wildcards

In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific). The wildcard is never used as a type argument for a generic method invocation, a generic class instance creation, or a supertype.

The following sections discuss wildcards in more detail, including upper bounded wildcards, lower bounded wildcards, and wildcard capture.

'Java > Java' 카테고리의 다른 글

[Java] JDK Download  (0) 2013.04.02
[Java] Creating Custom Annotations and Using Them  (0) 2013.01.21
[Java] JConsole 연결 옵션  (0) 2013.01.05
[Java] Java 모니터링 툴 VisualVM Download  (0) 2012.12.28
[java] Heap Memory Size 구하기  (0) 2012.12.26
posted by 뚱2

[.Net] CodeDomProvider

.Net/.Net 2013. 1. 15. 18:20

링크 : http://msdn.microsoft.com/ko-kr/library/system.codedom.compiler.codedomprovider.aspx 

 

using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Microsoft.CSharp;
using Microsoft.VisualBasic;
using Microsoft.JScript;

// This example demonstrates building a Hello World program graph 
// using System.CodeDom elements. It calls code generator and
// code compiler methods to build the program using CSharp, VB, or
// JScript.  A Windows Forms interface is included. Note: Code
// must be compiled and linked with the Microsoft.JScript assembly. 
namespace CodeDOMExample
{
    class CodeDomExample
    {
        // Build a Hello World program graph using 
        // System.CodeDom types.
        public static CodeCompileUnit BuildHelloWorldGraph()
        {
            // Create a new CodeCompileUnit to contain 
            // the program graph.
            CodeCompileUnit compileUnit = new CodeCompileUnit();

            // Declare a new namespace called Samples.
            CodeNamespace samples = new CodeNamespace("Samples");
            // Add the new namespace to the compile unit.
            compileUnit.Namespaces.Add(samples);

            // Add the new namespace import for the System namespace.
            samples.Imports.Add(new CodeNamespaceImport("System"));

            // Declare a new type called Class1.
            CodeTypeDeclaration class1 = new CodeTypeDeclaration("Class1");
            // Add the new type to the namespace type collection.
            samples.Types.Add(class1);

            // Declare a new code entry point method.
            CodeEntryPointMethod start = new CodeEntryPointMethod();

            // Create a type reference for the System.Console class.
            CodeTypeReferenceExpression csSystemConsoleType = new CodeTypeReferenceExpression("System.Console");

            // Build a Console.WriteLine statement.
            CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(
                csSystemConsoleType, "WriteLine",
                new CodePrimitiveExpression("Hello World!"));

            // Add the WriteLine call to the statement collection.
            start.Statements.Add(cs1);

            // Build another Console.WriteLine statement.
            CodeMethodInvokeExpression cs2 = new CodeMethodInvokeExpression(
                csSystemConsoleType, "WriteLine",
                new CodePrimitiveExpression("Press the Enter key to continue."));

            // Add the WriteLine call to the statement collection.
            start.Statements.Add(cs2);

            // Build a call to System.Console.ReadLine.
            CodeMethodInvokeExpression csReadLine = new CodeMethodInvokeExpression(
                csSystemConsoleType, "ReadLine");

            // Add the ReadLine statement.
            start.Statements.Add(csReadLine);

            // Add the code entry point method to
            // the Members collection of the type.
            class1.Members.Add(start);

            return compileUnit;
        }

        public static void GenerateCode(CodeDomProvider provider,
            CodeCompileUnit compileunit)
        {
            // Build the source file name with the appropriate
            // language extension.
            String sourceFile;
            if (provider.FileExtension[0] == '.')
            {
                sourceFile = "TestGraph" + provider.FileExtension;
            }
            else
            {
                sourceFile = "TestGraph." + provider.FileExtension;
            }

            // Create an IndentedTextWriter, constructed with
            // a StreamWriter to the source file.
            IndentedTextWriter tw = new IndentedTextWriter(new StreamWriter(sourceFile, false), "    ");
            // Generate source code using the code generator.
            provider.GenerateCodeFromCompileUnit(compileunit, tw, new CodeGeneratorOptions());
            // Close the output file.
            tw.Close();
        }

        public static CompilerResults CompileCode(CodeDomProvider provider,
                                                  String sourceFile,
                                                  String exeFile)
        {
            // Configure a CompilerParameters that links System.dll
            // and produces the specified executable file.
            String[] referenceAssemblies = { "System.dll" };
            CompilerParameters cp = new CompilerParameters(referenceAssemblies,
                                                           exeFile, false);
            // Generate an executable rather than a DLL file.
            cp.GenerateExecutable = true;

            // Invoke compilation.
            CompilerResults cr = provider.CompileAssemblyFromFile(cp, sourceFile);
            // Return the results of compilation.
            return cr;
        }
    }

    public class CodeDomExampleForm : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button run_button = new System.Windows.Forms.Button();
        private System.Windows.Forms.Button compile_button = new System.Windows.Forms.Button();
        private System.Windows.Forms.Button generate_button = new System.Windows.Forms.Button();
        private System.Windows.Forms.TextBox textBox1 = new System.Windows.Forms.TextBox();
        private System.Windows.Forms.ComboBox comboBox1 = new System.Windows.Forms.ComboBox();
        private System.Windows.Forms.Label label1 = new System.Windows.Forms.Label();

        private void generate_button_Click(object sender, System.EventArgs e)
        {
            CodeDomProvider provider = GetCurrentProvider();
            CodeDomExample.GenerateCode(provider, CodeDomExample.BuildHelloWorldGraph());

            // Build the source file name with the appropriate
            // language extension.
            String sourceFile;
            if (provider.FileExtension[0] == '.')
            {
                sourceFile = "TestGraph" + provider.FileExtension;
            }
            else
            {
                sourceFile = "TestGraph." + provider.FileExtension;
            }

            // Read in the generated source file and
            // display the source text.
            StreamReader sr = new StreamReader(sourceFile);
            textBox1.Text = sr.ReadToEnd();
            sr.Close();
        }

        private void compile_button_Click(object sender, System.EventArgs e)
        {
            CodeDomProvider provider = GetCurrentProvider();

            // Build the source file name with the appropriate
            // language extension.
            String sourceFile;
            if (provider.FileExtension[0] == '.')
            {
                sourceFile = "TestGraph" + provider.FileExtension;
            }
            else
            {
                sourceFile = "TestGraph." + provider.FileExtension;
            }

            // Compile the source file into an executable output file.
            CompilerResults cr = CodeDomExample.CompileCode(provider,
                                                            sourceFile,
                                                            "TestGraph.exe");

            if (cr.Errors.Count > 0)
            {
                // Display compilation errors.
                textBox1.Text = "Errors encountered while building " +
                                sourceFile + " into " + cr.PathToAssembly + ": \r\n\n";
                foreach (CompilerError ce in cr.Errors)
                    textBox1.AppendText(ce.ToString() + "\r\n");
                run_button.Enabled = false;
            }
            else
            {
                textBox1.Text = "Source " + sourceFile + " built into " +
                                cr.PathToAssembly + " with no errors.";
                run_button.Enabled = true;
            }
        }

        private void run_button_Click(object sender,
            System.EventArgs e)
        {
            Process.Start("TestGraph.exe");
        }

        private CodeDomProvider GetCurrentProvider()
        {
            CodeDomProvider provider;
            switch ((string)this.comboBox1.SelectedItem)
            {
                case "CSharp":
                    provider = CodeDomProvider.CreateProvider("CSharp");
                    break;
                case "Visual Basic":
                    provider = CodeDomProvider.CreateProvider("VisualBasic");
                    break;
                case "JScript":
                    provider = CodeDomProvider.CreateProvider("JScript");
                    break;
                default:
                    provider = CodeDomProvider.CreateProvider("CSharp");
                    break;
            }
            return provider;
        }

        public CodeDomExampleForm()
        {
            this.SuspendLayout();
            // Set properties for label1
            this.label1.Location = new System.Drawing.Point(395, 20);
            this.label1.Size = new Size(180, 22);
            this.label1.Text = "Select a programming language:";
            // Set properties for comboBox1
            this.comboBox1.Location = new System.Drawing.Point(560, 16);
            this.comboBox1.Size = new Size(190, 23);
            this.comboBox1.Name = "comboBox1";
            this.comboBox1.Items.AddRange(new string[] { "CSharp", "Visual Basic", "JScript" });
            this.comboBox1.Anchor = System.Windows.Forms.AnchorStyles.Left
                                    | System.Windows.Forms.AnchorStyles.Right
                                    | System.Windows.Forms.AnchorStyles.Top;
            this.comboBox1.SelectedIndex = 0;
            // Set properties for generate_button. 
            this.generate_button.Location = new System.Drawing.Point(8, 16);
            this.generate_button.Name = "generate_button";
            this.generate_button.Size = new System.Drawing.Size(120, 23);
            this.generate_button.Text = "Generate Code";
            this.generate_button.Click += new System.EventHandler(this.generate_button_Click);
            // Set properties for compile_button.
            this.compile_button.Location = new System.Drawing.Point(136, 16);
            this.compile_button.Name = "compile_button";
            this.compile_button.Size = new System.Drawing.Size(120, 23);
            this.compile_button.Text = "Compile";
            this.compile_button.Click += new System.EventHandler(this.compile_button_Click);
            // Set properties for run_button.
            this.run_button.Enabled = false;
            this.run_button.Location = new System.Drawing.Point(264, 16);
            this.run_button.Name = "run_button";
            this.run_button.Size = new System.Drawing.Size(120, 23);
            this.run_button.Text = "Run";
            this.run_button.Click += new System.EventHandler(this.run_button_Click);
            // Set properties for textBox1.        
            this.textBox1.Anchor = (System.Windows.Forms.AnchorStyles.Top
                                     | System.Windows.Forms.AnchorStyles.Bottom
                                     | System.Windows.Forms.AnchorStyles.Left
                                     | System.Windows.Forms.AnchorStyles.Right);
            this.textBox1.Location = new System.Drawing.Point(8, 48);
            this.textBox1.Multiline = true;
            this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(744, 280);
            this.textBox1.Text = "";
            // Set properties for the CodeDomExampleForm.
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(768, 340);
            this.MinimumSize = new System.Drawing.Size(750, 340);
            this.Controls.AddRange(new System.Windows.Forms.Control[] {this.textBox1,
                this.run_button, this.compile_button, this.generate_button,
                this.comboBox1, this.label1 });
            this.Name = "CodeDomExampleForm";
            this.Text = "CodeDom Hello World Example";
            this.ResumeLayout(false);
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
        }

        [STAThread]
        static void Main()
        {
            Application.Run(new CodeDomExampleForm());
        }
    }
}

 

'.Net > .Net' 카테고리의 다른 글

[.Net] NuGet  (0) 2013.01.23
[.Net] AOP 프로그래밍  (0) 2013.01.23
[.Net] Aspect Oriented Programming With .Net  (0) 2013.01.14
[.Net] 웹 자동화 구현 클래스  (0) 2013.01.09
[.Net] pinvoke.net  (0) 2013.01.07
posted by 뚱2

링크 : http://msdn.microsoft.com/ko-kr/library/k9x6w0hc(v=vs.80).aspx 

 

public class Bus
{
    // Static constructor:
    static Bus()
    {
        System.Console.WriteLine("The static constructor invoked.");
    }

    public static void Drive()
    {
        System.Console.WriteLine("The Drive method invoked.");
    }
}

class TestBus
{
    static void Main()
    {
        Bus.Drive();
    }
}

'.Net > C#' 카테고리의 다른 글

[C#] Visual Studio TODO 만들기  (0) 2013.01.30
[C#] Form close와 Dispose  (0) 2013.01.28
[C#] Assemble.load  (0) 2013.01.15
[Visual Studio 2010] C# 선언할때 공백 제거 문제  (0) 2013.01.14
[C#] C# as 연산자  (0) 2013.01.09
posted by 뚱2

[C#] Assemble.load

.Net/C# 2013. 1. 15. 12:22

링크 : http://msdn.microsoft.com/ko-kr/library/system.reflection.assembly.load.aspx

 

어셈블리를 로드합니다.

이 멤버는 오버로드됩니다. 구문, 사용법 및 예제를 비롯하여 이 멤버에 대한 자세한 내용을 보려면 오버로드 목록에서 이름을 클릭합니다.

이름 설명
Public 메서드정적 멤버 Load(AssemblyName) 해당 AssemblyName이 지정된 어셈블리를 로드합니다.
Public 메서드정적 멤버 Load(Byte[]) 내보낸 어셈블리가 포함된 COFF(Common Object File Format) 기반 이미지를 사용하여 어셈블리를 로드합니다.이 어셈블리는 호출자의 응용 프로그램 도메인에 로드됩니다.
Public 메서드정적 멤버 Load(String) 긴 형식의 이름으로 지정된 어셈블리를 로드합니다.
Public 메서드정적 멤버 Load(AssemblyName, Evidence) 사용되지 않습니다. 해당 AssemblyName이 지정된 어셈블리를 로드합니다.어셈블리는 제공된 증명을 사용하여 호출자의 도메인에 로드됩니다.
Public 메서드정적 멤버 Load(Byte[], Byte[]) 생성된 어셈블리가 들어 있고 경우에 따라 어셈블리에 대한 기호도 포함하는 COFF(공용 개체 파일 형식) 기반 이미지를 사용하여 어셈블리를 로드합니다.이 어셈블리는 호출자의 응용 프로그램 도메인에 로드됩니다.
Public 메서드정적 멤버 Load(String, Evidence) 사용되지 않습니다. 해당 표시 이름이 지정된 어셈블리를 로드한 다음 제공된 증명을 사용하여 이 어셈블리를 호출자의 도메인에 로드합니다.
Public 메서드정적 멤버 Load(Byte[], Byte[], Evidence) 사용되지 않습니다. 생성된 어셈블리가 들어 있고 경우에 따라 어셈블리에 대한 기호 및 증명 정보도 포함하는 COFF(공용 개체 파일 형식) 기반 이미지를 사용하여 어셈블리를 로드합니다.이 어셈블리는 호출자의 응용 프로그램 도메인에 로드됩니다.
Public 메서드정적 멤버 Load(Byte[], Byte[], SecurityContextSource) 생성된 어셈블리가 들어 있고 경우에 따라 기호도 포함하고 보안 컨텍스트의 소스도 지정하는 COFF(공용 개체 파일 형식) 기반 이미지를 사용하여 어셈블리를 로드합니다.이 어셈블리는 호출자의 응용 프로그램 도메인에 로드됩니다.
위쪽

'.Net > C#' 카테고리의 다른 글

[C#] Form close와 Dispose  (0) 2013.01.28
[C#] 정적 생성자 (static 멤버 초기화)  (0) 2013.01.15
[Visual Studio 2010] C# 선언할때 공백 제거 문제  (0) 2013.01.14
[C#] C# as 연산자  (0) 2013.01.09
[C#] StackTrace  (0) 2013.01.08
posted by 뚱2

링크 : http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1010406&docId=147593598&qb=a3Qg6rO17Jyg6riwIOyEpOyglQ==&enc=utf8§ion=kin&rank=1&search_sort=0&spq=0&pid=gIMg/c5Y7tVssafJgqCssc--212138&sid=T6OCbM95o08AABCxC2s 

'Network' 카테고리의 다른 글

단일호스트의 부하  (0) 2013.12.24
[Telnet] 해당 포트가 살아 있는지 확인 할때는 telnet 을 이용  (0) 2013.01.06
[KT EGG] 스트롱에그 KWD-B2600  (0) 2012.09.20
[Ping] KT 핑 테스트  (0) 2012.06.30
[Util] Ping Test Easy  (0) 2012.04.06
posted by 뚱2

선언할때 줄 잘 맞춰서 코딩해 놨는데 공백이 사라지는 억울함이....

 

도구 -> 옵션 -> 텍스트 편집기 -> C# -> 서식 -> 간격 -> 기타 간격 옵션을 설정합니다. -> 선언문의 공백을 무시합니다.

' 체크 '

 

 

'.Net > C#' 카테고리의 다른 글

[C#] 정적 생성자 (static 멤버 초기화)  (0) 2013.01.15
[C#] Assemble.load  (0) 2013.01.15
[C#] C# as 연산자  (0) 2013.01.09
[C#] StackTrace  (0) 2013.01.08
[C#] DllImportAttribut  멤버  (0) 2013.01.04
posted by 뚱2

 

posted by 뚱2

링크 : http://www.devpia.com/NET2/EvaCast/Lecture/?fCode=2&sCode=5&c=9 

링크 : http://aspectdotnet.codeplex.com/

링크 : https://www.facultyresourcecenter.com/curriculum/pfv.aspx?ID=8658&c1=en-us&c2=0



자바에서 정말 편하게 사용했던 AspectJ 


닷넷에 와서 비슷하걸 찾고 있는데 내 입맛에 맞는걸 아직 찾지 못했다.


시간을 두고 좀더 찾아봐야 할 것 같다.

'.Net > .Net' 카테고리의 다른 글

[.Net] AOP 프로그래밍  (0) 2013.01.23
[.Net] CodeDomProvider  (0) 2013.01.15
[.Net] 웹 자동화 구현 클래스  (0) 2013.01.09
[.Net] pinvoke.net  (0) 2013.01.07
[.Net] Windows 서비스 응용 프로그램  (0) 2012.12.07
posted by 뚱2