Yii에서 아주 강력한 도구인 gii 를 활성화 하는 방법 입니다.

webroot/myblog/protected/config/main.php

스크린샷 2012 07 26 오후 2 29 28

에서 gii 에 대한 패스워드 설정 후 http://localhost/myblog/index.php?r=gii  를 열게 되면 gii 로 들어 갈수 있습니다.

당연히 gii 에 대한 확장도 할 수 있습니다. 예를 들어 기본적으로 제공하는 Model 생성이 mysql 및 몇몇 DB 에만 활성화 되어 있다면 MongoDB 관련한 생성을 확장으로 사용가능 합니다.

 스크린샷 2012 07 26 오후 2 34 13

       - MongoDB 관련 자동 생성 extension 을 설치한 상태 입니다.

Controller 는 Controller 생성 입니다. 각각 화면은 설명이 잘 나와있으니 보시면 이거구나 하실꺼예요.. ^^ 개발하시는 분들은 당연히 그냥 아실 것 같습니다.

Model 생성이 재미 있습니다. 

 

가장 효율적으로 작성하는 프로젝트 개발 순서는 

  1. DB 설계

  2. Model Generator  

      - model 을 생성하기 위해서는 기본적으로 config/main.php 에서 DB 설정을 해주셔야 합니다.

스크린샷 2012 07 26 오후 2 41 32

      - Model 폴더 안에 관련 Model 파일 하나가 생성됩니다.

  3. Crud Generator

      - 만들어진 model 을 기준으로 하여 기본적인 생성, 읽기,수정,삭제 기능이 되는 화면 및 콘트롤러를 생성합니다.

      - Controller 파일 하나와 views 에 작성된 Controller 명으로 폴더가 하나 생성되고 그 아래에 Crud 에 대한 파일들이 생성됩니다.

 

작성한 기능에 대한 화면으로 들어가게 되면 디자인 되지 않은 상태에서의 기본적인 CRUD 가 다 되는 폼이 작성되게 됩니다.

만약 post 라는 테이블의 글이라면 PostController 가 생성되니 url 은 http://localhost/myblog/index.php?r=post  가 됩니다. 그러면 view/post/index.php 가 동작하겠죠? ^^

메뉴도 구성되어 있습니다. Create , admin 이 기본적으로 있습니다.   바로 사용할려면 안됩니다.  Login 을 해야 사용 가능하니까요. 

그 기능은 자동 생성된 PostController 에서 filters 메서드와 accessRules 에 작성되어 있습니다. 

다 접근 가능하게 하실려면 잠시 filters 메서드에서 'accessControl' 을 주석처리 해주시면 권한 체크를 통과 합니다.

layout 을 바꿔주고 싶으시면 해당 Action Method에서 $this->layout->'//layouts/xxx'; 로 변경하시면 됩니다.

 

참 쉽죠?? ^^

 

 

 

신고
posted by Bloody Guy

Yii Framework 설치하기

Develop 2012.07.26 14:17

Yii Framework 설치하기 입니다.

 

Yii Framework 을 Download 합니다.

webroot 에 설치하시면 됩니다.

스크린샷 2012 07 26 오후 12 17 40

설치후 이것저것 참 많은데요.. 일단 마음 비우고

설치 레퍼런스를 따라 합니다.

webroot 에서

./yiiroot/framework/yiic webapp [ Web Name ]

[ Web Name ] 은 webroot에서 폴더 명이 됩니다.

ex) ./yiiroot/framework/yiic webapp myblog

webroot / myblog

               / yiiroot

가 됩니다.

yiic 배치 프로그램입니다.

기본적인 환경이 다 구성되요.

스크린샷 2012 07 26 오후 1 59 35

myblog 하위로 생성된 폴더 구조 및 파일 입니다.

protected 폴더가 실제 php 코드를 작성하는 위치 입니다. 주요한 폴더만 설명합니다.

 - components : 공통으로 작성되는 코드들의 위치 

                         - WebUser , UserIdentity , Controller 작성시 공통 등...

 - controllers : Controller 코드 작성

 - views : View 코드 작성

              - layouts : 마스터 페이지 처럼 Top , Menu , bottom 기본 작성을 하고 공통으로 사용 

 - models : model 코드 작성

 - config : 기본 설정 php

               - main.php : DB 설정 및 gii 사용 설정 autoload 등 yii 에서 필요한 기본 환경을 관리

 - extensions : yii 확장 기능 관리 폴더

정상적으로 설치가 완료 되었다면 http://localhost/myblog/ 로 접속이 되고 자동 작성된 페이지가 보이게 됩니다.

 

설치 완료!!!! ^^

신고
posted by Bloody Guy

PHP Yii Framework 들어가기...

Develop 2012.07.26 11:37

최근 1년 정도 php 와 objective-c 만을 사용해서 개발해왔는데 이번에 약간의 시간이 있어 Yii Framework 을 살짝 정리를 해서 두고 두고 잘 써볼까 합니다.

Yii Framework 은 php 관련 Framework 을 검색해다가 php framework 중 1위를 차지하고 있어서 사용하였는데 국내에는 정보가 많이 없습니다.

Yii Framework 을 알기 전까지는 cakephp , codeigniter 를 사용했었습니다.

cakephp , codeigniter 다 장단점이 있었습니다.

감히 3개 중에 어떤게 가장 강력하다고 개인적으로 물어본다면 Yii 를 선택합니다.

 

장점

 - 강력한 자동 생성도구 gii

 - MVC ( cakephp , codeigniter 도 mvc 입니다. )

 - 많은 extension

단점

 - 약간은 과장된 흥보 ( 디자이너도 개발자 없이 쉽게 만들수 있어요.  ㅡ,.ㅡ;  보니 불가 할듯 합니다. php 도 잘해야하고 뷰가 어떻게 나눠지고 위젯 등이 어떻게 구성되어야 하는지도 알아야 합니다. )

 - 한국어 레퍼런스가 거의 없습니다.

    반면 cakephp 나 codeigniter 의 경우는 한국어 레퍼런스도 많고 codeigniter 는 한국어로 전체 번역하여 서비스 해주는 곳도 있습니다.

 

다른 Framework 은 접어 두고 Yii 로 돌아가서..

퀵 동영상 메뉴얼 입니다.  4개만 봐도.. 아.. 이놈... 생산 속도가 빠르겠구나... 생각이 드실거라 생각합니다. (^^ 최근에 드는 생각은 Web 개발의 진정한 갑은 java, .net 이 아닌 php 가 web 의 진정한 갑이라는 생각이 많이 드네요.)

아마존에서 에서 판매하는 Yii Framework 서적   입니다.  킨들에디션으로 사면 반값이네요 ^^

한번 읽어 보고 싶지만 영어라.. 후들 후들..... ^^;

여유가 되시는 분들은 한번 읽어보시면 많은 도움이 될것 같네요 ^^

 

Yii 의 MVC 패턴 입니다.

스크린샷 2012 07 26 오후 12 11 23

widget을 잘사용하면 잘 분리해서 뷰 공통 및 작업량을 많이 줄일 수 있습니다.

 

Browser 에서 Request 가 발생하게 되면 실제 호출되는 Flow 입니다.

스크린샷 2012 07 26 오후 12 11 35

참!!! 쉽죠!! ^^

 

신고
posted by Bloody Guy

 

새로 작성하게 된 App 의 기능 중 Theme 기능이 검토 되었습니다.

XCode3 와는 다르게 Resource 라는 폴더가 없어져서 딱히 Bundle 에 Folder 구조로 어떻게 넣을지를 몰라 헤메이다가 소 뒷걸음에 넣었습니다.

알고보니 간단하네요..

1. Project 파일에서의 Targets 에서 "Build Phases" 를 보시면 아래와 같이 나옵니다.

 

2. 화면에서 "Copy Bundle Resources" 에서 "+" Click

 

3. 상세 아이템을 선택하라고 나오게 됩니다. "Add Other..."

 

4. Finder 가 나오면 추가할 폴더를 추가하시구요.. 선택 하시면 "Create folder references for any added folders" 를 선택하세요.

4.1 "Create groups for any added folders" 는 app 의 bundle root 에 이미지를 동일이름이 있을경우 하나만 놔두고 나머지는 무시합니다.

4.2 "Create folder references for any added folders" 는 Folder 를 참조 하고 파일이 추가 되거나 할경우 폴더 구조를 포함합니다.

 

 

5. Finish 하시면 추가 된 폴더를 볼수 있어요..

 

끝입니다.

 

확인 할수 있는 방법은 시물레이터 빌드 하시고 app 의 페키지를 확인하시면 폴더 구조대로 들어가 있습니다.

해당 폴더에 대한 경로는 "/theme/각이미지" 로 바로 접근 가능합니다. ^^

끝..... 하면 섭섭하니... 추가 Class Source 올립니다.

 

Theme 에 대한 경로 관련 하여 바로 사용할 수 있도록 작성한 내용입니다.

@implementation ThemeMng

 

 

+(NSString*) Path:(NSString*) name

{

return [NSString stringWithFormat:@"/theme/%@/%@",[UserSettingMng getUserSettingOfPlist:@"ThemeName"],name];

}

 

+(void) ChangeTheme:(NSString*) themeName

{

[UserSettingMng setUserSettingOfPlist:@"ThemeName" Value:themeName];

}

 

@end

 

딱 보시면 다들 아시겠죠? ^^

질문은 댓글로 해주세요..

 

즐거운 하루 보내세요!

 

 

 

 

 

신고
posted by Bloody Guy

CoreData를 처음 접하고 예전의 사용 습관 때문에 작성하게된 BaseRepository...

목적은 CRUD 는 걍 했으면 좋겠다.. 입니다.

 

Header

#import <Foundation/Foundation.h>

 

@interface BaseRepository : NSObject

 

@property (strong , nonatomic) NSString *entityName;

 

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;

 

-(id) initModel;

 

- (NSMutableArray*) getAll;

 

- (id) getByID:(id) objectID;

 

- (void) updateModel:(id) modelObj;

 

- (void) deleteMdoel:(id) modelObj;

 

- (id) getRelation:(id)target attrName:(NSString*) attrName;

 

- (NSMutableSet*) getRelationList:(id)target attrName:(NSString*) attrName;

 

- (NSManagedObjectContext *)getMObjContext;

 

-(NSMutableArray*) sortForNSMutableArray:(NSMutableArray*)list sortName:(NSString*)sortName;

 

 

@end

 

Body

#import "BaseRepository.h"

#import "AppDelegate.h"

 

@implementation BaseRepository

 

@synthesize managedObjectContext;

@synthesize entityName;

 

-(id) initModel{

return [NSEntityDescription insertNewObjectForEntityForName:[self entityName] inManagedObjectContext:[self getMObjContext]];

}

 

- (void) deleteMdoel:(id) modelObj{

NSError *error;

[[self getMObjContext] deleteObject:modelObj];

if (![[self getMObjContext] save:&error]) {

NSLog(@"%@",[error localizedDescription]);

}else{

NSLog(@"success to delete!");

}}

 

 

- (void) updateModel:(id) modelObj

{

NSFetchRequest *retrieveRequest = [[NSFetchRequest alloc] init];

NSEntityDescription *friend = [NSEntityDescription entityForName:[self entityName] inManagedObjectContext:[self getMObjContext]];

 

[retrieveRequest setEntity:friend];

NSError *error;

if (![[self getMObjContext] save:&error]) {

NSLog(@"%@",[error localizedDescription]);

}else{

NSLog(@"success to update!");

}

}

 

-(NSManagedObjectContext *)getMObjContext{

if (managedObjectContext == nil) {

managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];

}

return managedObjectContext;

}

 

-(NSManagedObjectContext *)OrgGetMObjContext{

if (managedObjectContext == nil) {

managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];

}

 

return managedObjectContext;

}

 

 

- (NSMutableArray*) getAll

{

NSEntityDescription *user = [NSEntityDescription entityForName:[self entityName] inManagedObjectContext:[self getMObjContext]];

NSFetchRequest *retrieveRequest = [[NSFetchRequest alloc] init];

 

[retrieveRequest setEntity:user];

NSError *error;

 

NSMutableArray *friendList = [[[self getMObjContext] executeFetchRequest:retrieveRequest error:&error] mutableCopy];

 

return friendList;

}

 

- (id) getByID:(id) objectID

{

//CoreDataDelegate *coredatadelegate = [[CoreDataDelegate alloc] init];

return nil;

}

 

- (id) getRelation:(id)target attrName:(NSString*) attrName

{

return [target valueForKey:attrName];

}

 

- (NSMutableSet*) getRelationList:(id)target attrName:(NSString*) attrName

{

return [target mutableSetValueForKey:attrName];;

}

 

-(NSMutableArray*) sortForNSMutableArray:(NSMutableArray*)list sortName:(NSString*)sortName{

NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:sortName ascending:YES];

NSArray *sorter = [NSArray arrayWithObject:sortByName];

[list sortUsingDescriptors:sorter];

return list;

}

 

@end

 

 

 

작성이후...

지나고 보니.. 꼭 필요 없는 부분같게 느껴집니다.

장점은 각 Model 에 대한 Repository 를 분리해서 나름(?) 편하게 써본다 입니다.

생성조건 패턴을 Repository 에서 처리를 했었는데...

Model 에서 그냥 할껄.. 이라는 생각도 많이 드네요...

Model override 해서 처리 했어도 될만한 일이였습니다.

뭐. 이렇게 삽질하면서.. 얻는거죠. 허허허

 

-- 3월 5일 추가됨 --

CoreDtata schema 에서 변경이 된 경우 자동 생성했을때 작성된 내용이 사라집니다. 손수 변경된 내용에 대해서는 추가 작업을 진행해야 합니다.

동일한 Model을 상속받아서 추가 구현을 하는 것이 좋은 방법으로 보이네요.

그렇게 한다음에 이쁘게.. 처리 해봐야 겠습니다.

 

 

신고
posted by Bloody Guy

앱스토어에 등록한 앱이 리젝 됐습니다. 

아 맘아파라.

리젝된 사유는 등록한 앱의 설명을 쓰는 곳에서 스크린 샷이 문제 였습니다.

앱에 IAd 를 사용하도록 하였는데 그 IAD 의 테스트 메세지가 보여진것이 문제였습니다.

이 화면이 문제였습니다.

"Test Advertisement"  이 화면 덕분에 다시 Waiting for Review 로 들어갔네요.. 

1주일을 기다렸는데 또 다시 1주일을 더 기다려야 될지 모르겠네요.


다른 분들은 이거 실수 하시지마세요.. ^^




추가 정보 입니다.

http://www.facebook.com/note.php?note_id=244298205610544


정책이 자주 바뀌나 보네요.. 허허허...

 

신고
posted by Bloody Guy

삼성 SDS에서의 교육자료 합니다.

신고
posted by Bloody Guy
사전지식
 com+
 spring.net

서문
Spring.net을 통해 com+ 을 사용하시는 분들이 당연히 많으실꺼라 의심하지 않는다. 
이번해 테스트 겸 작업을 진행하며 모호한 부분들에 대해서 정리할 심산으로 작성한다.
어짜피 내가 실력이 허접해서 좀 피곤했을 수도 있다. ^^;

많은 사람들이 com+ 의 장점과 단점을 알고 있고 그리고 그 장점을 활용하기 위해 각종 설정과 등록과정등을 거쳐 드디어 사용하고자 하는 test 용 또는 client 프로그램을 실행하여 테스트를 시작한다.
그나마 3tier , 4tier 가 흔한 개발 환경에서 해당 com+ 을 리모팅 , Webservice , wcf 등으로 서비스로서 제공한다면 그 서버 기능들 까지 활성화 해가며 테스트를 해야한다.
.net 2.0 이후 System.Transaction 기능이 들어오면서 메서드 단위 Transaction 이 되고 MTS 를 위해 꼭 com+ 을 등록안해도 MTS 가 사용가능한 환경이 왔지만 com+ 또 다른 장점인 객체 관리 기능에 대해 무시 할 순 없다.
Spring 의 가장 강한 장점인 IoC 로서 com+ 로의 등록 목적이 아닌 component 도 com+ 로 등록할수 있도록 Service 를 제공한다.
그외에도 Service(webservice, remoting, wcf 등(?) )들에 대해서도 spring container 를 통해 서비스가 가능하다.
이렇게 됨으로써 이제 개발 환경과 배포 환경을 완전히 분리 가능하다.
예를 들어 하나의 dll 로 config를 통해 webservice , remoting , wcf 로 서비스 가능하고 com+ 로 등록이 되도록도 가능하다. 
 그런데 이글의 내용의 포커스가 com+ 에 대한 사용 방법일까? 
 솔찍히 다른 서비스에 대해서는 별다른 이질감 없이 바로 적용할 수 있었다 ( 그만큼 springframework.net 의 메뉴얼은 잘되어 있었다.) 그러나 com+ 과 관련한 내용이 좀 적고 com+ 에 대한 이해가 없으면 안될만한 내용이 있어 지극히 개인적으로 관리 목적으로 적고 그리고 혹시나 저 처럼 고생하는 분들이 없으면 좋겠다 라는 마음에 작성하게 되었다. ^^ 마음껏 욕(?)해주시면 감사하겠다.

본문
1. 아주 간단한 dll 을 하나 작성한다.

이게 다다 자 이것을 이제 com+ 에 등록할수 있게 만들어야 한다. 말그대로 테스트(?) 인것이다.
이게 하나의 dll 로서 EnterObject.dll 로 작성된다.

여기서 주의 사항이 하나 있다. Com+ 로 등록시 IAddService 라는 것이 안보인다. Library 형식으로 com+ 서비스가 등록되었다면 별다른 문제가 없다. 만약 com+ 에 Server 형식으로 서비스가 된다면 문제가 된다. 이 문제를 해결하기 위해 AssemblyInfo.cs 에 있는 ComVisible(false) ComVisible(true)  설정 한다.
Library 형식과 Server 형식의 차이점을 모르신다면 검색해서 확인 한번 해보시면 com을 이해하는데 도움이 될꺼라고 생각한다. 

이렇게 함으로써 차후 com+ Service 등록후의 IAddService 라는 Interface 형식이 노출된것을 확인해볼수 있다.
( 등록된 com+ 의 Interface 로서 IAddService 가 등록된것이 보이는가?  ^^ )




2. 이제 com+ 을 등록할 window 또는 console  Project 를 하나 더 추가한다.
이 프로젝트 정말로 할꺼 없다. 단순히 Com+ 에 대한 등록만을 전담한다. 
정말이지 많이 본 내용 아닌가? 샘플에도 있다. 샘플보다 몇가지를 더 추가한것 정도이다.
코딩으로 하면 각 클래스에 종속적으로 다 설정되어야 하는 내용들이다. 
AddService 가 보이는가?
당연히 등록 되어 있어야 한다.

이제 com+ 의 설정부분을 보겠다.
자. 여기에서 주의 할점  ActivationMode 는 기본적으로 library 이다. 그러나 나는 Server가 의미가 있으므로 Server 로 설정한다. (만약 library 도 상관없다면 이 글이 아니라. spring 에서 제공해주는 것만으로도 충분하다.) , 그리고 Property name 중 Assembly 가 보이는가? 이것은 먼저 만든 EnterObject 라는 샘플 dll 을 어떤 dll 이름으로 노출할지에 대한 설정이다. ( 나는 여기서 오해 했다 만들 Assembly 명인가?? 라는 생각을..... 난 바보였다.  ㅠㅠ )
이렇게 대략 spring 과 관련된 정보들을 셋팅하고 빌드 한다. 그러면 참 서비스 좋게도 자동으로 com+ 로 등록까지 자동으로 해주신다. ( 아 ... 편해..~~! ) 그리고 Assembly 에 등록한 value 이름으로 dll 도 하나 만들어 주신다. ( 빌드 패스에 있다. )
여기서 극악의 장점? 단점? 테스트는 해보지 않았으나 만약 EnterObject 에서 com+ 로 등록할 클래스를 2개 만들고 Assembly 로 2개를 노출하게 되면 물리적으로 2개로 분리가 가능할것으로 보이나 테스트는 나중으로 미룬다... 하.하.하. ( 확인해 보았더니 잘!!! 된다.!!! )

이렇게 하고 난후 샘플에서 제공 하는 방법으로 서비스 받으면 된다. 혹시 귀찮으신 분들을 위해.
자.. 끝났다.. addComponent 라는 이름으로 등록된 com+ 의 기능을 enter 라는 이름으로 끌어내 사용하면 된다.

여기서 추가로.. com+ 로 등록된 이 addComponent 를 바로 remoting 이나 wcf , webservice 로 오픈 가능할까?  답은..... 가능하다.. 이다. ( 너무 당연한 이야긴가? ^^;; )

추가로 이렇게 remoting으로 서비스 후 com+ 등록 내용이 변경 되었을 경우 remoting 의 재시작 없이 com+ 의 shutdown 만으로 수정된 내용이 반영된다. ( 이걸 위해서 였다. 흑흑... ㅠㅠ ) 혹시 이 방법 말고서비스의  끈김없는 pooling 이 가능 한 방법을 안다면 알려주시면 감사하겠다. ( 혹시나 iis app pool 은 테스트 해보았고 잘되는 것도 확인 하였다. 그러나 web 기반 서비스 이다 보니 속도 문제가 있어서... )

중간에 큰 작업없이 일을 진행할려고 하다보니 이런모습으로 작업된것 같다. 

p.s. 혹시 질문 있으시면 email 도 좋고 리플도 좋으니 이런부분들에 대한 정보를 공유 했으면 좋겠습니다. ^^





 

신고
posted by Bloody Guy

NHibernate

Develop/Nhibernate 2009.07.27 23:59
Hibernate 의 .net 버젼으로 NHibernate 가 나왔다. ( 아주 오래 됐다..)
NHibernate 를 사용하여 3~4개의 프로젝트를 진행하면서 NHibernate 의 강력함과 매력에 많이 빠져 들게 되었었다.

그리고 프로젝트중에 ORM 으로서의 기능을 다하지 못한 부분들에 대한 아쉬움과 어떻게 하면 저 잘 사용할수 있을지에 대해 많은 고민과 생각을 하게 되었다.

실력이 미흡하나마 조금씩 정리해 나갈려고 한다.

신고
posted by Bloody Guy

ORM 의 이해

Develop/ORM 2009.07.27 23:53
ORM 이란?
객체와 관계형 table 사이의 mapping을 처리해 주는 것을 Object Relational Mapping ( ORM ) 이라고 한다.

ORM 이 제공하여야 하는 기능
ORM 은 객체를 table에 저장해 주고, table에 저장된 data로 부터 객체를 생성해 주는 기능을 제공한다.

  • Metadata를 사용하여 object 와 table 사이의 mapping 정보를 지정할 수 있어야 한다.
    • 손쉽게 mapping 정보를 변경할 수 있도록 해야 한다.
  • class 상속, 객체 사이의 연관 등을 객체 modeling을 지원해야 한다.
  • class 와 class의 property를 사용하여 객체를 조회할 수 있어야 한다.
  • 객체 값 변경을 자동으로 database에 반영해야 한다.
  • 상황에 따라 성능을 개선할 수 있는 방법을 제공해야 한다.
    • Lazy loading
    • join 기반 조회
    • native query
    • cache

ORM의 장점.

  • 생산성 향상
    • SQL query를 작성하고 그 query 실행 결과로 부터 객체를 생성하는 코드를 작성하는 시간이 줄어들어 business logic 에 집중할 수 있다.
  • 유지보수 용이
    • JDBC, ADO.NET API 를 사용한 코드 축소
    • 코드가 business logic 위주로 작성되기 때문에 이해도 상승
    • 리펙토링 용이
  • 특정 DBMS에 종속적이지 않다.
    • 대부분의 ORM 솔루션은 DBMS에 종속적이지 않다.

ORM의 단점

  • DAO 패턴에 익숙한 개발자에게는 초반 접금이 어렵다.
    • 객체 지향적으로 class 설계하는 것은 쉽지 않다.
  • ORM 을 잘못 사용할 경우 성능을 저하시킬 수 있다.
    • ORM 솔루션들은 자체적으로 cache와 같이 성능을 향상 시킬 수 있는 기능을 제공하고 있기 때문에 ORM 자체의 성능은 나쁘지 않다. 그러나 부적절하게 ORM 을 적용할 경우 성능 저하를 유발할 수 있다.
  • 객체 지향적 프로그래밍이 아니라면 별다른 효과를 볼 수 없다.
    • OLAP 이나 프로시져가 많은 시스템과 같은 곳에서는 ORM 을 사용한다 하더라도 객체 지향적인 장점을 활용할 수 없다.
신고
posted by Bloody Guy

VC# Friend assembly

Develop/C# 2008.05.30 16:47

friend assembly 에 대해 불과 몇분전에 알았다.
개별적으로 정의가 가능한 StrongNameIdentityPermission 클래스를 통해서도 공유할 수 있지만 차이점이 있다.
MSDN 발췌.
1. friend 어셈블리는 전체 어셈블리에 적용되는 반면 StrongNameIdentityPermission은 개별 형식에 적용됩니다.
2. A 어셈블리에 B 어셈블리와 공유하려는 형식이 매우 많은 경우에는 일일이 StrongNameIdentityPermission을 사용하여 지정해야 하지만, friend 어셈블리를 사용하면 friend 관계를 한 번만 선언하면 됩니다.
3. StrongNameIdentityPermission을 사용하는 경우에는 공유하려는 형식은 public으로 선언되어야 합니다. friend 어셈블리의 경우에는 공유되는 형식은 private으로 선언됩니다.
4. 어셈블리에 있는 public이 아닌 형식에 액세스할 수 있는 .netmodule을 빌드하는 방법에 대한 자세한 내용은 /moduleassemblyname을 참조하십시오.

문제가 발생한 계기는 TestCode 를 작성하면서 발생하였다. 내부적인 함수에 대해 어떻게 테스트 할것인가가 관건이었고 이문제에 대한 해결책으로 friend assembly 를 찾아서 적용했다.

프로젝트 A 의 AssemblyInfo.cs 파일에 프로젝트 B 에 대한 정보 아래와 같이 주게 되면 프로젝트 B에서는 A에 있는 접근 한정자가 internal 형식이 접근 가능하다.
[assembly: InternalsVisibleTo("프로젝트 B")]
이로서 프로젝트 B 에서는 프로젝트 A 에 있는 internal 의 경우 접근 가능하고 프로젝트 C 는 접근 불가능하다.

만약 strong name이 사용된 어셈블리에 사용할 수 있는 내부 형식과 멤버를 만드는 방법
키파일을 생성하고 공개 키를 표시하려면 sn.exe 명령의 다음과 같은 시퀀스를 사용합니다.
sn -k friend_assemblies.snk // Generate strong name key
sn -p friend_assemblies.snk key.publickey // Extract public key from key.snk into key.publickey
sn -tp key.publickey // Display public key stored in file'key.publickey

key.publickey 에 대한 결과를 컴파일러에 키파일을 전달합니다.
[assembly: InternalsVisibleTo("프로젝트 B , PublicKey=39485737483asdfsafa")]   //셈플

그리고 프로젝트 B는 strong name key인 friend_assemblies.snk 를 등록하여 사용한다


아... 문서 정리를 잘하고 싶은데. 시간이 여의치가 않네요.. 에효..

신고
posted by Bloody Guy

Web.config 에서 httpHandlers 에서 *.aspx 파일에 대한 핸들을 다른 객체로 변경했을 경우 아주 당연한 이야기 겠지만 사용이 불가능하다.

more..


기본적으로 설정되지 않으나. springframework.net 사용시 aspx 파일에서 injection 에 대한 관리를 하기 위해서 설정 한다.

설정하지 않았을시 aspx 파일에서는 injection 되지 않는다.

다른 방법으로 사용하여야 하는데 springframework 의 ContextRegistry의 GetContext 를 이용하여
해당 타입을 가져 올수 있다.

<Sample Code>
public CtrlType getSeesionObject<CtrlType>(string CtrlTypeName)
{
    IApplicationContext ctx = ContextRegistry.GetContext();
    return (CtrlType)ctx[CtrlTypeName];
}

그리고 Injection을 Ctrl class 를 별도로 두어 Page 에서는 해당 object 들에 대한 injection 을 한다.

신고
posted by Bloody Guy
제어역행(IoC) 는 스프링 프레임워크의 핵심이다.
제어역행의 의미는 무엇인가?

마틴파울러는 2004년의 글에서 제어의 어떤 측면이 역행되는 것인지에 대한 의문을 제기했다. 그는 의존하는 객체를 역행적으로 취득하는 것이라는 결론을 내렸다. 그는 그와 같은 정의에 기초하여 제어 역행이라는 용어에 좀더 참신한 "의존성 주입(dependency injection)" 이라는 이름을 지어줬다.

Ioc 를 적용함으로써 객체들은 시스템 내의 각 객체를 조정하는 어떤 외부의 존재에 의해 생성 시점에서 의존성을 부여 받는다. 즉 의존성이 객체로의 주입(inject) 된다는 말이다.
따라서 IoC는 한 객체가 협업해야 할 다른 객체의 참조를 취득하는 방법에 대한 책임의 역행이라는 이미를 갖는다.


신고
posted by Bloody Guy

infragistics의 grid인 UltraGrid의 내용을 Excel로 다운을 받을 수 있습니다.

이건 문제도 아닙니다.. 아주 단순하게 UltraWebGridExcelExporter 를 사용하면 아주 간단하게 처리 됩니다.

Asp.net의 Design Page 에서 UltraWebGridExcelExporter 콘트롤을 drag & drop 을 하고

Button을 하나 만들어서 UltraWebGridExcelExporter 클래스의 Export 함수를 호출해서 파라메터로 UltraWebGrid 콘트롤을 넘기면 됩니다.

그러나 이렇게 했을 때 문제는 Grid의 Header가 2줄 이상이었을 때 Export 만으로 Multi Header를 만들어 주지 않습니다.

예를 들어

 

이런 헤더를 Excel 에서 볼 수 없다. 아래에 있는 실제 column 정보만 나오게 됩니다.

Multi Header 의 작업을 하기 위해서는 일반적으로 다른 콘트롤 즉 DataGrid 를 사용하여 RenderControl 함수를 사용 실제 Excel 페이지를 만들어서 써야 합니다.. 이것도 얼마나 괴로운 작업인가요... 케에에엑~~~!!!


그나마 UltraGrid를 그대로 사용하면서 UltraWebGridExcelExporter 를 사용하여 멀티해더를 좀 억지로 구현을 했습니다.

사용한 객체는 Infragistics.WebUI.UltraWebGrid.ExcelExport.BeginExportEventArgs 를 사용했습니다.

보면 알겠지만 BeginExportEvent 를 사용한 것입니다.

이 객체의 CurrentWorksheet를 사용했습니다.

셈플소스 방식은

_ultraExcelExportBeginEvnt.CurrentWorksheet.Row[0].Cell[0].Value = "입력할 값";

이 것으로 일단 Excel 의 원하는 곳에 값을 입력할 수 있습니다.

그리고는 폰트 색이며 라인 등.. 그리는 과정을 반복하게 됩니다.

그러나 실제 그렇게 많은 멀티라인은 존재하지 않기 때문에 코딩이 아무래도 일일이 만드는 것보다는 훨씬 적게 듭니다.

Multi header 를 구현하면 위쪽에 해더가 없는.. 즉.

"D" 같은 column과 "그룹헤더"를 볼 수 있습니다. 이런 column은 MergedCellsRegions 를 사용하여 병합 시킵니다.

_ultraExcelExportBeginEvnt.CurrentWorksheet.MergedCellsRegions.Add( 시작 Row , 시작 Column , 종료 Row , 종료 Column );

로 셀 병합이 가능합니다.


색을 칠하는 것도 문제가 됩니다.. 각 RowCell 마다 CellFormat 이 존재하고 CellFormatFillPatternSolid 로 맞춰

FillPatternForegroundColor 를 변경함으로써 색을 변경하였습니다..

라인은 LeftBorderColor LeftBorderStyle 로 각각 라인과 색을 맞추었습니다..


이로써 UltraWebGridExcelExporter 로 멀티해더를 구현했습니다.


해놓고 보면 아무것도 아닌것인데 어떻게든 코드 수를 줄일 방법과 좀더 명시적인 방법을 찾다 보니 이렇게 되었습니다..

검색해서도 답이 나오지 않고 검증된 것도 없어 결국 삽질로…

예로 그냥 단순히 "멀티헤더를 못해요! 따로 만드세요"라는 영문으로 된 사이트를 볼수 있었습니다.

누군가 질문글을 올려놓은 것도 보았는데 답이 없었습니다.


혹시 이렇게 하는 것보다 쉽게 하는 방법이 존재한다면 좀 알려주세요.

신고
posted by Bloody Guy

Visual Studio 2005의 강력한 기능들 중 하나인 "가상 웹 서버" 기능을 사용하다 문제가 발생했습니다.

그것은 경로 문제…

배포 되어야 하는 서버의 경로 위치와 가상 웹 서버의 경로가 틀린 것이 문제가 되어 각 이미지 경로를 변경해야 했는데

개발할 때 배포할 때의 문제를 해결하기 위해서 가상 서버의 경로를 변경할 수 있는 방법을 찾아야 했습니다.

 

열심히 찾아본 결과 webdev.webserver.exe 라는 실행 파일을 찾을 수 있었습니다.

해당 파일의 경로는

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727

실행을 하게 되면 해당 옵션이 상세히 들어 납니다.

포트 번호 설정, 물리 경로 설정, 가상 경로를 설정할 수 있습니다.

사용 샘플까지 상세히 나와 사용하는데 불편함이 없습니다.

 

그리고 추가로 프로젝트 속성을 변경해야 할 필요가 있습니다.

이유는 디버깅을 하기 위한 설정입니다.

 

VS WEB 프로젝트의 변경해야하는 속성은

바로 빨간색으로 박싱을 한 부분입니다.

변경한 가상 웹 서버의 경로로 지정을 해주면 되겠습니다.

 

신고
posted by Bloody Guy

읽기 쉬운 코드를 작성하기란 결코 쉬운 작업이 아니다.

컴퓨터가 이해할 수 있는 코드는 어떤 방식이 되든

문법만 맞는다면 전혀 문제 없이 작동하게 된다.

그러나 내가 작성한 것을 다른 사람이 본다면

참 쉽지 않을 것이다.


프로젝트를 여기 저기 다니다 보면 하던 것을 맡을 때도

신규로 새로 할 때도 있다.

대체로 하던 것은 받은 사람은 앞에 작성한 것에 대한

질타와 "왜 이렇게 했지? 무슨 뜻이지?" 등등

자기와의 코딩 방식이 달라서 각종 이야기가 나온다.


왜 그럴까?

공부 해왔던 방법이나 사용하는 방식, 그리고 가장 큰 이유는

프로그래밍 철학이 달라서 일 것이다.


아래의 코드들은 동일한 역할을 하는 코드들이다.

아주 간단하게 숫자 둘 중에 큰 수를 반환하는 함수이다.

예제 1)


예제 2)


어떤 것이 맘에 드는가?

보는 사람마다 다를 것이다.

"한 줄에 쓰겠다." , "여러 줄에 걸쳐 명시적으로 쓰겠다." 등

그리고 그것에 대해서 이유를 다 들 수 있을 것이다.


만약 코드를 책을 보듯이 볼 수 있다면 어떨까?

위의 코드를 책으로 읽는다면


예제1의 경우는 하나, 하나 짚고 넘어가면서 정확히 구분하는 용어(if)의 사용으로

영어 단어 뜻을 좀 안다면 이해할 수 있을 것 같다.


예제2의 경우는 내가 만약 물음표(?) 연산자를 모른다면 이해하기 어려울 것이다.

그러면 찾아봐야 하고 어떻게 움직이는 지 알아야 한다.


예제1을 "동화책" 예제2를 "시" 라고 표현해도 될 것 같다.


조금씩 알아가면서 우아한 코드를 지향하고 좀더 줄이고 좀더 함축적인 것을

사용하는 것이 과연 얼마나 효율적인가에 대해 고민 한다면 그것에 대한 답은

간단하게 나올 것이다.


수준이 높아질수록 시를 쓰고 싶어하고 동화책을 멀리하게 된다.

그러나 문제는 시를 많이 쓸수록 그것을 이해하는 사람은 그 것에 대한

매니아가 아니면 알아보기 힘들다.


아주 간단한 예로써 큰 값 구하기를 사용하였지만

아주 복잡한 업무 프로세스 라든지 제고관리 각 종 분기점에 해당하는

모든 경우가 될 수 있다.


당신은 시인만을 위한 시를 쓸 것인가?

아니면 대중을 위한 글을 쓸 것인가?

결정해야 할 것이다.

신고
posted by Bloody Guy

기본에 충실하자.

Develop/Tips 2007.11.30 17:57

간혹 이야기하는 중에 서로 다른 것을 가지고 같은 것처럼 이야기하는 경우를 본다.

사용하는 단어가 틀린 것인가 이해관계가 다른 것인가

뭔가 이유가 있을 법한데. 이런 경우 대체로 양보란 있을 수 없고

자기만 맞다 라고 주장한다.

대체로 논리적이지 않고 우기기에 들어가는 이유는 딱 한가지. 어디서 곁다리로 들은 것은 많은데

기본이 없으니 의미도 모르는 대충 짐작으로 때려잡은 기술적 용어를 남발…… 스스로 무덤에 서서히

빠져들게 된다. 그리고 붙는 별명… "우기기 대마왕~~"


내공(기본)이 강하신분들은 대체로 아주 논리적으로 상대를 설득하게 된다.

"당신이 틀리고 내가 맞다" 라고 이유와 근거를 제시하면서


기본이 없으면 높이 올라가기가 상당히 힘들다.

그 기본이란 게 무엇일까 라는 고민을 한다.


단지 문법을 아는 게 기본일까?

절.대. 아니다. 라고 생각한다.


항상 기본에 충실하자…


신고
posted by Bloody Guy

행복한 개발자…

Develop/Tips 2007.11.28 16:09

   

김명호 박사님의 "행복한 개발자가 됩시다." 라는 말씀이 참 쉽지 않음을 생각하게 된다.

김명호 박사님이 말씀하시는 기본.. 그것은 항상 새로운 기술과 새로운 움직임이 평준화하게 될 때

당연히 그것들은 기본이 될 것이고 그 기본은 당연히 알아야 한다. 라는 뜻으로 이해 했다.

새로운 기술에 대한 탐구를 즐기고 그것을 행복해 할 수 있는 개발자.

멋지다.

나도 그렇게 노력해야 한다.

당연하다.

   

왜? 난 개발자라는 직업을 가졌으므로..


항상 비판적인 사고와 미래지향적인 사고가 필요하다. 


참고 기사(한국 MS 최고기술임원 김명호)

http://www.dt.co.kr/contents.htm?article_no=2007112102012469704005

신고
posted by Bloody Guy

Toad 팁

Develop/Tips 2007.11.27 10:34

Toad 에서 키보드 방향키가 안될 때 조치 방법입니다.

   

=======================================================================

1. Close TOAD.

   

2. Locate the PLSQLKEYS.bin file, by default this file is located at:

Toad 8.0 & Earlier - C:\Program Files\Quest Software\TOAD\Temps

Toad 8.5 & Later - C:\Program Files\Quest Software\Toad for Oracle\User Files

   

3. Rename the PLSQLKEYS.bin file to PLSQLKEYS_old.bin.

   

4. Restart TOAD. Launching TOAD will automatically recreate the PLSQLKEYS.bin file, resolving the issue.

=========================================================================

   

토드 종료 후

   

Toad 8.0 & Earlier - C:\Program Files\Quest Software\TOAD\Temps

Toad 8.5 & Later - C:\Program Files\Quest Software\Toad for Oracle\User Files

   

경로에서

   

PLSQLKEYS.bin 파일 삭제

   

   

   

신고
posted by Bloody Guy

Enum 열거형

Develop/C# 2007.11.23 10:04

누군가 나에게 enum 안에 있는 상수 집합을 Loop로 처리 할 수 있는 방법을

물었다.


Enum 구조체에 존재하는 GetNames 로 string [] 로 가져 올 수 있다. 해당 타입에 대해서 정의해 줘야 한다.

만약 enum 변수에 대한 것이라면

이렇게도 된다.

반대로 GetValues 도 사용할 수 있다. 딱 보면 알겠지만 enum 의 상수 값 배열을 반환한다

Int [] iEnumList = Enum.GetValues(testEnum.GetType());

Foreach ( int iEnum in iEnumList) 가 되겠다.

Enum 구조체의 네임스페이스는 System 이고 ValueType 을 상속받고

구현된 인터페이스는 IComparable , IFormattable 및 IConvertible 이다.


혹시 귀차니즘에 빠져 MSDN을 등한시 하시는 분들을 위해 MSDN 화면 캡쳐를 동봉한다.

http://msdn2.microsoft.com/ko-kr/library/system.enum_members(VS.80).aspx


신고
posted by Bloody Guy


티스토리 툴바