'분류 전체보기'에 해당되는 글 189건

  1. 2010.03.30 사용자 이름 / 비밀번호 인증을 사용하는 간단한 WCF 서비스
  2. 2010.03.30 구글 TTS 가지고 놀기
  3. 2009.12.27 로그인 기능
  4. 2009.12.25 SMS 발송기 3
  5. 2009.12.25 파일 업로더 1
  6. 2009.12.25 폴더 비주얼라이저
  7. 2009.12.24 미옥씨
  8. 2009.12.07 LINQ to SQL Tips and Tricks
  9. 2009.11.21 未必的故意
  10. 2009.11.07 C# 코딩 연습, 분할 정복과 이벤트

사용자 이름 / 비밀번호 인증을 사용하는 간단한 WCF 서비스

RTFM/WCF 2010. 3. 30. 11:00

http://codebetter.com/blogs/peter.van.ooijen/archive/2010/03/22/a-simple-wcf-service-with-username-password-authentication-the-things-they-don-t-tell-you.aspx

WCF 인증 방법에는 여러 가지가 있지만, 그 중 가장 실용적인 것은 사용자 이름과 비밀번호를 사용하는 것이 아닐까 합니다.

그런데 WCF의 사용자 이름 / 비밀번호 인증은 쉽다면 쉽고 어렵다면 어려워, 이에 관한 수많은 아티클이 있습니다.

이 아티클 역시 그 중 하나입니다.

추신 : 제가 알기로 전세계에서 가장 잘 쓴 WCF 책은 우리나라에서 나왔는데, 그 제목이 유수석의 WCF 바이블이라고 합니다.

:

구글 TTS 가지고 놀기

RTFM/기타 2010. 3. 30. 10:51

http://www.codeproject.com/KB/audio-video/GoogleTTS-Ebook-Reader.aspx

아티클의 샘플은 C++로 되어 있지만, 서비스 자체는 HTTP를 사용하니 어떤 환경에서도 사용할 수 있겠습니다.

생각보다 TTS의 품질이 좋네요.

솜이슬이나 요즘 구상하고 있는 모바일 앱에 적용하여도 괜찮을 것 같습니다.

:

로그인 기능

로앤비 툴즈/파일 업로더 2009. 12. 27. 01:40
로앤비 툴즈의 개발 원칙 중 한 가지가 '가급적 슬림하게 가자'는 것이었습니다.
그래서 파일 업로더에서는 업로드 하는 사용자를 식별하기 위해 아이디와 비밀번호로 로그인을 요구하는 대신, 엉성하나마 IP 주소로 식별을 하고 있었습니다.

하지만 곰곰히 생각해 본 결과, 아무래도 아이디/비밀번호 기반의 인증이 필요하다는 결론을 내렸습니다.
예컨데 이러한 파일 업로더의 사용 시나리오를 생각해 볼 수 있습니다.

1. 대회의실에서 프리젠테이션을 하기 위해 PPT 파일을 옮겨야 한다.
2. 자신의 컴에서 PPT 파일을 파일 업로더를 통해 업로더 한다.
3. 대회의실의 컴에서 파일 업로더를 실행시켜, PPT 파일의 주소를 확인한다.

IP 기반의 사용자 식별 방법으로는 자기의 자리에서 올린 파일을 대회의실의 컴에서 볼 수 있는 방법이 없습니다.
역시 로그인이 답인 듯 합니다.

어쩔 수 없이 로그인 인증을 도입했지만, 그래도 최대한 간략하게 구현하였습니다.
1. 등록 항목을 아이디와 비번, 두 가지만 받습니다. (월소득, 주소, 주거 형태(자가/전세/월세), 지난 대선 지지 후보 등은 입력하지 않으셔도 됩니다.)
2. 자동 로그인을 설정하면 프로그램이 실행될 때 자동으로 로그인이 됩니다.  

추신 : 계정 등록과 로그인은 파일 업로더에서만 사용됩니다. 다른 모든 프로그램은 로그인이 필요 없으며, 어떠한 데이터도 서버에 저장하지 않습니다. 
:

SMS 발송기

로앤비 툴즈/SMS 발송기 2009. 12. 25. 02:37

무엇에 쓰는 물건이느뇨?

잘 아시면서… SMS를 발송하는 툴입니다.

 

어떻게 쓰느뇨?

1. 보낼 메세지와 보내는 사람의 전화번호를 입력합니다..

image

2. 받는 사람을 주소록에서 선택하거나 직접 입력합니다.

아웃룩 연락처는 아웃룩의 연락처를 읽어 와서 받는 사람에 추가하는 기능인데, 현재는 구현되어 있지 않습니다.

지금은 주소록이 비어 있으므로 직접 입력하도록 하겠습니다.

3. 직접 입력란에 받는 사람의 전화번호를 입력하고 추가 버튼을 누릅니다.

받는 사람이 여러 명이면, 이 작업을 반복합니다.

image

4. 보내기 버튼을 눌러 SMS를 발송합니다.

image

5. 받는 사람의 전화번호가 주소록에 있지 않는 번호라면 주소록에 추가할 수 있는 화면이 열립니다.

추가할 사람의 이름을 입력하고 추가 버튼을 누릅니다.

image

image

6. 전호번호 왼쪽의 + 를 클릭하면 해당 전화번호로 발송한  내역이 표시됩니다.

image

7. 주소록의 데이터는 자동으로 저장이 되지만, 필요에 따라서 내보내거나 가져올 수 있습니다.

image

8. 주소록에서 오른쪽 버턴을 누르면 컨텍스트 메뉴가 열립니다.

image

선택된 연락처를 받는 사람에 추가하거나 주소록에서 제거할 수 있습니다.

:

파일 업로더

로앤비 툴즈/파일 업로더 2009. 12. 25. 01:30

무엇에 쓰는 물건이느뇨?

그림이나 문서 파일 등을 웹 서버에 업로드하고 그 URL을 얻은 후, 웹 페이지에서 접근할 수 있도록 합니다.

예컨데 우리 회사의 그룹웨어에서는 그림을 첨부하는 기능이 없는데, 이런 경우에 사용할 수 있습니다.

 

어떻게 쓰느뇨?

1. 찾아보기를 누르거나 드래그 앤 드롭으로 업로드할 파일을 선택합니다.

2. 업로드 버튼을 누르면 파일이 업로드됩니다.

업로드가 진행되는 동안에는 윈도우가 비활성 상태가 되고 진행상황이 표시됩니다.

3. 업로드가 완료되면 윈도우가 다시 활성 상태가 되고 업로드된 파일의 URL이 화면에 표시됩니다.

동시에 내가 업로드한 파일에도 내용이 추가됩니다.

4. 복사 버튼을 누르면 업로드된 파일의 URL이 클립보드로 복사됩니다.

5. 내가 업로드한 파일에서 마우스 오른쪽 버튼을 클릭하면 컨텍스트 메뉴가 열립니다.

A. 선택한 항목의 URL을 복사합니다.

예) http://d.lawnb.com/LawnBTools/a/ae7f1a847dfc4e9c8488cb3bd1f3d524.png

B. 선택한 항목의 URL을 <img> 태그에 넣어 복사합니다.

예) <img src="http://d.lawnb.com/LawnBTools/a/ae7f1a847dfc4e9c8488cb3bd1f3d524.png" />

C. 선택한 항목의 URL을 <a> 태그에 넣어 복사합니다.

예) <a href="http://d.lawnb.com/LawnBTools/a/ae7f1a847dfc4e9c8488cb3bd1f3d524.png" target="_blank" style="text-decoration:none">로앤비 툴즈.png</a>

D. 선택한 항목을 삭제합니다.

 

원 스텝 업로드

원 스텝 업로드를 체크하면, 위의 모든 과정을 한 번으로 수행합니다.

즉, 찾아 보기 혹은 드래그 앤 드롭으로 파일을 선택하면, 자동으로 업로드를 수행하고 업로드가 끝나면 생성된 URL을 클립보드로 복사합니다.

 

내가 업로드한 파일

파일을 업로드할 때 업로드한 컴퓨터의 IP가 같이 저장이 되는데, 이를 이용하여 내가 업로드한 파일을 구분합니다.

따라서 회사 컴에서 업로드한 파일이 집 컴에서는 내가 업로드한 파일로 인식되지 않습니다.

[업데이트 2009.12.27]

아이디/비밀번호 인증으로 변경되었기 때문에 로그인 한 아이디를 기반으로 내가 업로드한 파일을 구분합니다.

따라서 업로드한 장소에 상관없이 내가 업로드한 파일이 동일하게 표시됩니다.


주의 사항

1. 저작권에 위배되는 파일을 올리지 않습니다.

2. URL을 외부에 공개하여 과도한 트래픽을 유발하지 않도록 합니다.

 

우리 회사 게시판에 그림을 첨부하는 예제

1. 아래와 같이 첨부할 그림 파일을 파일 업로더에서 업로드합니다.

2. 이미지를 표시해야 하므로 <img> 태그의 src 속성에 파일 업로더에서 얻은 URL을 입력합니다.

이 때, HTML 태그 사용 체크 박스가 체크되어야 합니다.

[업데이트 2009.12.27]

<img> 태그로 복사와 <a> 태그로 복사 메뉴가 추가되었습니다.

3.  아래와 같이 이미지가 같이 표시되는 것을 확인할 수 있습니다.

:

폴더 비주얼라이저

로앤비 툴즈/폴더 비주얼라이저 2009. 12. 25. 00:52

무엇에 쓰는 물건이느뇨?

폴더(에 속한 파일들)의 크기를 계층적으로 비주얼하게 표시합니다.

하드 디스크의 용량이 부족한 경우에 유용하게 사용할 수 있습니다.

 

어떻게 쓰느뇨?

찾아보기를 눌러 폴더를 선택합니다.

왼쪽 폴더 목록에서 폴더를 선택하면 하위 폴더의 크기가 오른쪽 차트에 표시됩니다.

크기 순으로 상위 5개의 폴더는 차트에 표시되며, 나머지 폴더는 기타라는 이름으로 합쳐져 표시됩니다.

image

:

미옥씨

로앤비 툴즈/미옥씨 2009. 12. 24. 23:53

무엇에 쓰는 물건이느뇨?

매달 미옥씨에게 제출하는 비용영수증 양식을 편리하게 만들 수 있는 툴입니다.

 

어떻게 쓰느뇨?

1. 공통 정보를 입력합니다.

2. 자주 사용하는 세부사용내역이 있으면 단축키 1 ~ 10 에 입력해 둡니다.

 image

3. 비용영수증 하나 당 한 건씩을 그리드에 입력합니다.

이때 세부사용내역 외의 나머지 항목은 입력해 둔 공통 정보에서 자동으로 가져옵니다.

image

반복적으로 사용되는 세부사용내역은 단축키를 사용하여 입력하는 것이 편리합니다.

아래와 같이 세부사용내역에 커서가 있는 상태에서 CTRL 키와 함께 숫자 1에서 0 중 하나를 누르면 해당하는 단축키의 내용이 세부사용내역에 입력됩니다.

(키패드의 숫자키가 아닌 가로로 배열된 숫자키를 눌러야 합니다.)

image

4. 미리 보기를 눌러 출력될 형태를 확인한 후 출력을 합니다.

image

image

5. 불러 오기저장 하기 버튼을 클릭하면 그리드의 항목을 각각 XML 파일로 불러 오거나 저장할 수 있습니다.

image

6. 공통 정보와 단축키의 내용은 자동으로 저장됩니다.

:

LINQ to SQL Tips and Tricks

RTFM/C# 2009. 12. 7. 11:34

http://www.codeproject.com/KB/linq/LINQToSQLTips.aspx

Linq to SQL에 대한 몇 가지 팁 모음.

System.Data.Linq.SqlClient.SqlMethods 라는 클래스가 있다는 걸 처음 알았습니다.

 

참고로 damieng의 팁과 트릭도 덧붙입니다.

http://damieng.com/blog/2009/03/16/linq-to-sql-tips-and-tricks-1

http://damieng.com/blog/2009/04/12/linq-to-sql-tips-and-tricks-2

:

未必的故意

기록 2009. 11. 21. 00:58

미필적 고의 [未必的故意, dolus eventualis]

자기의 행위로 인하여 어떤 범죄결과의 발생가능성을 인식(예견)하였음에도 불구하고 그 결과의 발생을 인용(認容)한 심리상태.

출처 : http://100.naver.com/100.nhn?docid=67411

 

대학 시절,

너무나 심심해서 읽은 교과서에서 ‘미필적 고의’를 발견했을 때

손뼉을 짝 치며 좋아했었더랜다

 

바로 남녀의 일이 아닌가?

 

2009.11.20

:

C# 코딩 연습, 분할 정복과 이벤트

C# 코딩 연습 2009. 11. 7. 03:35

오늘은 OOP의 이론 중의 하나인 분할 정복에 대해서 (예제를 만들어 보며) 이야기 해보겠습니다.

아시다시피 ‘분할 정복’이란 커다란(복잡한) 문제를 작은(단순한) 문제들로 나눈 후, 나뉜 작은 문제들의 해를 구한 다음에,  이를 다시 결합하여 원래 문제의 해를 구하는 방법을 말합니다.

이는 OOP에서 말하는 캡슐화의 기반이 됩니다.

즉 수 많은 작업(메서드)이 있더라도 이를 몇 개의 클래스로 묶어 클래스 내부에서 처리하도록 하면(단순해진 작은 문제의 해를 구함), 외부에서는 각 클래스가 하는 일에 대해 구체적으로 알 필요가 없이 클래스 간의 통신만 관리하는(작은 문제들의 해를 결합) 식으로 문제를 단순화시킬 수 있다는 것입니다.

여기서 중요한 것은 클래스 간의 ‘통신’(OOP 용어로는 메시지 전달) 입니다. 어떤 작업을 처리하도록 요청 받은 클래스(이하 A)는 그 결과를 요청한 클래스(이하 B)에게 알려줘야 하는데, 이에는 두 가지 방법이 있습니다.

B가 A에게 물어보는 방법과 A가 스스로 B에게 알려주는 방법이 그것인데, 전자의 경우에는 B가 A의 메서드나 속성을 호출하여 반환값(혹은 속성값 또는 메서드의 out 매개변수 등)을 얻는 것이며, 후자는 B가 A의 이벤트에 대해 이벤트 핸들러를 설정해 두면 후에 B가 A의 이벤트 핸들러를 호출하는 방법입니다.

물론 전자의 방법이 좀 더 직관적이고 사용이 간편하지만, 결정적인 한계가 있습니다. 바로 B가 얻고자 하는 값이 결정되는 시점을 A만이 알고 있는 경우가 있을 수 있다는 것입니다. 그래서 이런 경우에는 B가 A의 메서드(값을 물어보는)를 호출하는 것이 아니라, A가 B의 메서드(값을 알려주는)를 호출하는 식으로 구현이 되어야 합니다.

즉 호출의 방향이 B –> A 에서 A –> B 순으로 반대가 됩니다. (참고로, 그래서 C/C++ 에서는 ‘콜백 함수’ 라는 용어를 사용하며 이는 함수(를 가리키는) 포인터로 구현됩니다.)

정리를 하자면, 복잡한 문제를 단순화 시키기 위해서는 여러 개의 클래스로 나누어 구현을 할 필요가 있는데, 이 때 클래스 간의 통신에 이벤트가 중요한 역할을 한다는 것입니다.


말로 설명하자니 다소 추상적인 느낌이 나는데, 그럼 실제로 예제를 만들어 보면서 분할 정복의 의미에 대해서 생각을 해보지요.

이번 연습에서 만들 프로그램은 사용자 목록 관리입니다.

상단에서 각 조건을 입력하고 검색 버튼을 누르면, 가운데 그리드에 해당하는 사용자의 목록이 나타나고, 하단에는 그리드에서 선택된 사용자의 상세 항목이 나타납니다. 추가 / 수정 / 삭제 기능이 더해지면 전형적인 업무용 프로그램의 형태라고 할 수 있겠네요.

어떤 식으로 구현하면 좋을까요?

간단하니까 윈폼 클래스 하나에다 모든 코드를 추가할 수도 있겠지만, 예제처럼 간단한 형태가 아니라 아주 복잡한 폼이라면 폼 하나의 코드가 매우 길어질 수 있습니다. (제 경험으로는 윈폼 하나의 코드가 천 라인이 넘으면 코드를 장악하기가 어려웠습니다.)

대신에 검색 / 그리드 / 상세정보 라는 세 개의 클래스로 나누어 각종 로직을 분담시키는 것은 어떨까요?

검색 클래스를 예로 들자면, 생년월일 체크 박스가 체크되었을 경우에만 DateTimePicker 컨트롤들이 활성화 되는 로직이나, 나이 TextBox에는 자연수만이 입력되어야 한다는 등의 로직은 검색 클래스만이 알고 있으면 될 것입니다. 이를 그리드나 상세정보 클래스가 알 필요는 없지요. 결국 검색 클래스는 사용자가 입력한 검색 조건에 대한 유효성 검사를 한 후에, 그리드 클래스에 검색 버튼이 눌러졌다는 것을 알려주기만 하면 됩니다. 물론 이 때 검색 조건도 같이 알려줘야 하겠지요.

그렇다면, 위의 사용자 목록 폼은 검색과 관련된 로직은 가지고 있지 않아도 되어 코드가 한결 단순해집니다. 바로 분할과 정복이 일어난 것이지요. 물론 검색 클래스를 다른 폼에서 재사용활 수 있다는 추가적인 장점도 생깁니다.


지금부터는 코드를 만들어 봅시다.

사용자 목록 폼, 즉 UI를 만들기 전에 데이터 액세스 레이어를 만들어 놓는 것이 좋겠네요.

물론 여기서는 DB에서 데이터를 가지고 오는 것이 가져오는 척만 하겠습니다. (이를 이른바 mock 클래스라고 하는데, 특히 단위 테스트에서 유용하게 사용됩니다.)

먼저 Employee 엔터티를 정의합니다.

mock 클래스인 EmployeeRepository도 추가합니다.

가운데 singleton 영역의 코드는 다음과 같습니다.

Repository 패턴을 흉내내기 위해 싱글톤으로 구현한 것인데, Repository 패턴이나 싱글톤 등은 본 포스트의 주제가 아니므로 지금은 따로 언급하지 않겠습니다.

다만 Search 메서드의 경우에는, LINQ to Object 를 이용하여 (검색 조건이 0개 부터 n개 일 수 있으므로 쿼리가 정해져 있지 않다는 의미에서) 동적 쿼리를 구현하는 테크닉입니다. LINQ to Object 뿐만 아니라 LINQ to SQL 이나 Entity Framework 에서도 유용하게 사용할 수 있습니다. (LINQ의 특징 중 하나인 ‘지연된 로딩’)


이제 검색 / 그리드 / 상세정보 클래스를 각각 구현할 것인데요, 이들은 모두 사용자 정의 컨트롤(유저 컨트롤)로 구현하는 게 좋을 것 같네요.

먼저 검색 컨트롤부터 추가합니다. 이름은 EmployeeSearchControl 정도가 좋겠네요.

윈폼 디자이너에서 그림과 같이 적당히 디자인 한 후 코드 비하인드 파일에 로직을 추가합니다.

붉은 밑줄이 그인 부분이 중요합니다. 이 컨트롤이 하는 일은 EmployeeRepository의 Search 메서드를 호출하는 것이 아닙니다. 실제 Search 메서드는 이 컨트롤의 컨테이너(사용자 목록 폼)에서 할 것이며, 이 컨트롤은 검색 버튼이 눌러졌다는 메시지를 호출하면서 그때 사용자가 입력한 값들(즉 검색조건)만 전달하면 됩니다.

물론 이 통지는 이벤트를 통해 구현하면 됩니다. SearchButtonClicked 라는 이벤트를 추가하면 되는데, 직접 입력하지 말고 이벤트 코드 생성기를 사용해봅시다.

이벤트 코드 생성기를 실행하고 아래와 같이 입력을 합니다.

이벤트 매개변수에는 Search 메서드가 필요로 하는 인자들이 들어있습니다.

이벤트 코드 생성기가 생성한 코드를 EmployeeSearchControl 에 추가합니다.

그 다음에는 이 이벤트를 발생시키는 코드를 추가해야 하는데, 이는 검색 버튼이 눌러지고 검색 조건에 대한 가공이 끝나 Search 메서드를 호출할 준비가 끝난 다음이 되어야 겠지요.

필수는 아니지만 보너스로 EmployeeSearchControl  클래스에 DefaultEvent 특성을 추가해줍니다.

DefaultEvent는 디자이너에서 EmployeeSearchControl 이 더블 클릭되었을 때 디자이너가 자동으로 추가할 이벤트 핸들러를 지정하는 일을 합니다.


이제 검색 클래스는 구현이 끝났습니다. 이어서 그리드 클래스와 상세정보 클래스를 구현하여야 할 터인데, 이는 지면 관계상 자세한 설명을 생략을 하겠습니다. (구체적인 코드는 첨부 파일을 참조하십시오.)

그리드 클래스의 이름은 EmployeeListControl 인데 디자인은 다음과 같습니다.

그리고 선택된 사용자가 변경될 때 발생하는 CurrentEmployeeChanged 와 사용자가 더블 클릭될 때 발생하는 EmployeeDoubleClicked 라는 두 개의 이벤트를 추가합니다.


상세정보 클래스는 EmployeeControl 라는 이름으로 추가하고 아래와 같이 디자인을 합니다.

EmployeeControl 은 아무런 이벤트도 가지고 있지 않습니다.


자 이제 위에서 작성한 유저 컨트롤들을 조립할 차례입니다.

사용자 목록 폼을 EmployeeListForm 라는 이름으로 추가한 후 디자이너에서 세 개의 유저 컨트롤을 각각 올립니다.

붉은 글씨는 각 컨트롤의 이름입니다.

사용자 목록 폼이 하는 일은 각 유저컨트롤 간의 통신을 중개하는 일입니다. 먼저 검색 컨트롤의 SearchButtonClicked 이벤트 핸들러를 추가합니다.

검색 컨트롤의 SearchButtonClicked 의 매개변수(즉 검색 조건)을 받아 EmployeeRepository.Search를 호출하여 검색을 수행한 후 그 결과를 그리드 컨트롤에 넘겨주고 있습니다.

위 이벤트 핸들러가 실행되고 나면 그리드 컨트롤에는 검색된 사용자의 목록이 나타나게 되겠네요.


이번에는 그리드 컨트롤의 이벤트 핸들러를 추가해 봅시다.

그리드에서 현재 사용자가 변경되면 상세정보 컨트롤에 이를 알려주고, 사용자가 더블 클릭되면 사용자 폼을 띄우는 일을 하고 있습니다.

(사용자 폼에 대한 코드는 여기서 살펴보지 않겠습니다. 첨부된 프로젝트 소스를 참고하십시오.)


정리하자면 사용자 목록 폼의 코드는 세 개의 이벤트 핸들러를 구현하는 것이 전부입니다.

검색 클래스 등을 만들지 않고 사용자 목록 폼에 모든 코드를 구현하는 것에 비하면 훨씬 간략하고 구조화되어 있기 때문에 재활용성이 높아 유지보수하기가 수월합니다.

또한 각 유저 컨트롤은 다른 폼에서도 사용할 수 있습니다. 여기서는 언급하지 않았지만 상세정보 컨트롤의 경우에는 사용자 목록 폼과 사용자 폼에서 두 번 사용되었습니다.


분할 정복의 장점은 바로 이런 것입니다.

복잡한 문제가 여러 개의 단순한 문제로 나누어 지기 때문에 해결하기가 쉽고, 이 과정에서 나누어진 단순한 문제는 다른 곳에서 재사용 될 수 있습니다.

OOP에서 클래스를 모델링 한다는 것은 바로 이렇게 문제를 나누어 가는 과정이라고도 할 수 있겠습니다.


말할 필요도 없겠지만, OOP는 프로그래밍 언어사에 있어 최고의 발명 중 하나이며, 발명된 지 한 세대가 지난 지금까지도 여전히 유용한 개념입니다.

세상 많은 일들이 그런 것처럼 OOP를 익히는 데도 왕도는 없는 것 같습니다. 글을 잘 쓰기 위해서는 많이 읽고 많이 쓰고 많이 생각해야 한다고 합니다. 좋은 프로그램을 짜기 위해서도 마찬가지가 아닐까 싶습니다. 좋은 코드를 많이 읽고, 좋은 코드를 많이 연습하고, 좋은 코드에 대해 많이 생각하는 것이 바로 OOP, 나아가서는 프로그래밍의 왕도가 아닐까 싶습니다.

예제 소스 :

: