1.5 라이브러리
.NET 프레임워크 기반의 라이브러리는 .NET 어셈블리라고 부릅니다.
.NET 어셈블리는 .NET 프레임워크 응용 프로그램을 구성하는 기본 컴포넌트입니다. 컴포넌트 기반의 프로그래밍은 모듈의 재사용성을 높여줍니다. .NET 응용 프로그램을 제작할 때 미리 작성된 라이브러리를 사용할 수 있는데 이 때 사용하는 라이브러리도 .NET 어셈블리이며 실행 파일도 .NET 어셈블리입니다.
.NET 어셈블리는 EXE 파일 혹은 DLL 파일 형태로 만들 수 있으며 하나 이상의 모듈을 포함할 수도 있습니다. .NET 어셈블리는 자기 기술적인 메타 데이터를 갖고 있고 레지스트리 항목에 종속되지 않는 구성 요소로 디자인되어 있기 때문에 병행(Side by Side) 실행이 가능합니다.
이로써 같은 명칭의 여러 어셈블리를 설치 가능할 뿐만 아니라 이를 사용하는 응용들은 자신들에 맞는 어셈블리를 사용할 수 있습니다.
1.5.1 .NET 어셈블리 구성 요소
.NET 어셈블리는 여러 종류의 구성 요소로 구성합니다.
첫 번째 구성 요소로 어셈블리 매니페스트가 있습니다. 어셈블리 매니페스트는 어셈블리의 버전 요구 사항과 보안 ID를 지정하는 데 필요한 모든 메타데이터와 어셈블리의 범위를 정의하고 참조를 확인하는 데 필요한 모든 메타 데이터를 포함하고 있습니다. 어셈블리 매니페스트는 어셈블리 이름, 버전 번호, 문화권, 강력한 이름의 정보, 어셈블리에 포함한 파일 목록, 형식 참조 정보로 구성합니다.
그리고 어셈블리에 정의된 형식들에 대한 형식 메타 데이터와 실제 수행해야 할 코드인 MSIL과 리소스로 구성합니다.
어셈블리는 하나의 물리적 바이너리로 만들어진 단일 파일 어셈블리와 여러 개의 물리적 바이너리로 만들어진 다중 파일 어셈블리로 나눌 수 있습니다. .NET에서는 어셈블리의 부속으로 사용하는 모듈을 만들 수 있는데 모듈은 어셈블리의 내용으로 포함합니다. 즉, 하나의 어셈블리가 다른 어셈블리에 있는 형식을 사용하기 위해서는 단순히 사용할 어셈블리를 참조만 하면 되는데 모듈에 있는 것을 사용할 때는 모듈을 포함하여 어셈블리를 만들어야 합니다.
그리고 .NET 어셈블리를 구성하는 물리적 바이너리에는 리소스 파일, 매니페이스, DLL, 모듈 등이 있습니다.
1.5.2 .NET 어셈블리 만들기
여기서는 .NET 어셈블리를 만들어 보기로 합시다. .NET 어셈블리 중에 실행 파일을 만드는 것은 이미 알고 있으므로 라이브러리를 만드는 것을 하겠습니다.
.NET에서 라이브러리는 쉽게 제작할 수 있습니다. 코드를 작성하는 부분에서 다른 어셈블리에서 사용할 수 있는 형식을 정의할 때 public 키워드를 명시합니다. 멤버도 마찬가지로 다른 어셈블리에서 접근을 허용하게 하려면 접근 지정을 public으로 설정합니다.
즉 다른 어셈블리에 정의된 형식이나 멤버 중에 사용할 수 있는 형식과 멤버는 접근 지정이 public으로 되어 있다는 것 말고는 차이가 없습니다.
public class Member
{
...중략...
public Member(string name, string addr)
{
...중략...
}
}
간단한 라이브러리를 하나 만들어 봅시다. 먼저 컴파일러 옵션을 이용하여 만드는 것을 보여 드리고 통합 개발 환경에서 만드는 것을 보여 드릴게요.
컴파일러 옵션을 이용하는 것을 보여 드리기 전에 메모장을 이용하여 소스 코드를 편집해 봅시다. 편집할 코드에는 다른 어셈블리에서 접근할 수 있는 Member 클래스와 접근할 수 없는 MemberInfo 클래스를 정의할게요.
그리고 Member에는 이름과 주소를 입력 인자로 받는 생성자와 이름 속성, 주소 속성의 get 블록을 public으로 접근 지정하여 다른 어셈블리에서 사용할 수 있게 합시다.
▷ 라이브러리 코드 예(Member.cs)
namespace MemberLib { public class Member //다른 어셈블리에서 접근 가능 { MemberInfo mi = null;
public string Name //다른 어셈블리에서 접근 가능 { get { return mi.Name; } } public string Addr //다른 어셈블리에서 접근 가능 { get { return mi.Addr; } } public Member(string name, string addr) //다른 어셈블리에서 접근 가능 { mi = new MemberInfo(name, addr); } public override string ToString()//다른 어셈블리에서 접근 가능 { return mi.ToString(); } }
class MemberInfo //다른 어셈블리에서 접근 불가 { internal string Name { get; private set; } internal string Addr { get; private set; } internal MemberInfo(string name, string addr) { Name = name; Addr = addr; } public override string ToString() { return Name; } } } |
Visual Studio 명령 프롬프트에서 csc /t:library /out:MemberLib Member.cs를 입력하시면 컴파일되어 MemberLib.dll 파일명으로 .NET 어셈블리가 만들어집니다.
[그림 1.3] csc 명령어를 이용하여 .NET 어셈블리 만들기
다음은 콘솔 명령어 csc의 옵션들입니다.
▷ 기본 옵션
/out:<file> 만들어질 어셈블리 이름(출력 파일 이름)을 지정 /target:exe 콘솔 실행 파일을 만들기 (기본) (약식: /t:exe) /target:winexe Windows 실행 파일을 만들기 (약식: /t:winexe) /target:library 라이브러리를 만들기 (약식: /t:library) /target:module 모듈을 만들기 (약식: /t:module) /delaysign[+|] 어셈블리 서명을 연기 /doc:<file> XML 문서 파일 생성 /keyfile:<file> 강력한 이름의 키 파일을 지정 /keycontainer:<string> 강력한 이름의 키 컨테이너를 지정 /platform:<string> 실행할 수 있는 플랫폼을 지정 (x86, Itanium, x64,anycpu) |
▷ 자주 사용하는 옵션
/reference:<file list> 어셈블리 참조 (약식:/r) /addmodule:<file list> 모듈을 포함 /help csc 커맨드 사용법 (약식:/?) /lib:<file list> 참조를 검색할 추가 디렉터리를 지정 |
Microsof Visual Studio로 라이브러리를 만들 때는 다음과 같이 새 프로젝트 템플릿에서 클래스 라이브러리를 선택하여 만들면 됩니다.
[그림 1.4] Microsoft Visual Staio에서 클래스 라이브러리 만들기
1.5.3 전용 어셈블리
이번에는 앞에서 만든 어셈블리를 전용으로 사용하는 방법에 대해 살펴보기로 합시다.
전용 어셈블리는 사용하는 응용 프로그램과 함께 어셈블리를 배포하여 해당 응용 프로그램에 의해서만 이용하는 어셈블리를 말합니다.
.NET에서 어셈블리 배포 방법의 기본은 전용으로 Microsoft Visual Studio에서 특정 어셈블리를 참조하면 자동으로 출력 폴더로 복사해 주어 개발자에게 편의성을 제공하고 있습니다. 솔루션 탐색기에서 참조 폴더에 마우스 우측 버튼을 클릭하여 나오는 컨텍스트 메뉴에서 참조 추가를 선택하여 원하는 어셈블리를 선택하세요.
[그림 1.5] 참조 추가창에서 추가할 어셈블리 선택하기
Microsoft Visual Studio에서 콘솔 응용 프로그램 프로젝트를 생성하여 작성한 어셈블리를 사용하는 코드를 작성해 봅시다.
▶ .NET 어셈블리를 참조하여 사용하는 응용 프로그램 예
using System; using MemberLib;
namespace UsingMemberLIb { class Program { static void Main(string[] args) { Member member = new Member("홍길동", "대한민국"); Console.WriteLine("이름:{0} 주소:{1}", member.Name, member.Addr); } } } |
▶ 실행 결과 이름:홍길동 주소:대한민국 |
물론 MemberLib에서 public으로 지정하지 않은 MemberInfo 형식과 멤버는 사용하지 못합니다.
참고로 CLR은 참조하는 전용 어셈블리의 위치를 찾는 일도 수행하는데 프로빙이라 합니다. 제일 먼저 응용 프로그램 디렉토리를 먼저 검사하고 없으면 구성 파일에 명시된 디렉토리를 검사합니다. 구성 파일은 응용 프로그램 구성 파일과 게시자 정책 파일, 시스템 구성 파일이 있으며 자세한 사항은 MSDN 런타임에서 어셈블리를 찾는 방법을 참고하세요.
1.5.4 공용 어셈블리
공용 어셈블리는 전역 어셈블리 캐시(윈도우즈 설치 폴더의 하위 폴더명이 Assembly인 폴더를 말함)에 있는 어셈블리를 말합니다. 전역 어셈블리 캐시에는 파일명과 확장자가 같더라도 어셈블리의 강력한 이름이 다르다면 배포할 수 있습니다.
[그림 1.6] 전역 어셈블리 캐쉬
강력한 이름은 어셈블리 이름, 버전 번호, 문화권, 어셈블리 ID, 공개 키, 디지털 서명 등으로 구성합니다. 이처럼 전역 어셈블리 캐시에는 같은 이름의 DLL도 강력한 이름이 다르면 배포할 수 있습니다. 이로써 서로 다른 버전을 사용하는 응용 프로그램들이 자신에게 맞는 어셈블리를 사용할 수 있는 것입니다. 이를 병행(Side by Side) 실행이라 합니다.
간단하게 라이브러리를 만들고 병행 실행을 확인합시다.
▶ DemoLib (버전 1.0.0.0)
using System; namespace DemoLib { public class DemoClass { public void Foo() { Console.WriteLine("Foo 1"); } } } |
공용 어셈블리를 만들기 위해 솔루션 탐색기에 프로젝트에 우측 마우스를 클릭하여 나오는 컨텍스트 메뉴에서 속성을 선택하세요. 그리고 서명 탭을 선택하신 후에 어셈블리 서명 체크 박스를 선택하시고 강력한 이름 키 선택 콤보 박스에서 새로 만들기를 선택합니다. 강력한 이름 키 만들기 창에서 키 이름을 입력하면 프로젝트 항목에 만든 키가 보이게 됩니다.
[그림 1.7] 어셈블리 서명
[그림 1.8] 강력한 이름 키 만들기
그리고 프로젝트를 빌드하시면 출력 폴더(기본: Debug)에 DLL 파일이 만들어집니다.
이제 작성한 DLL을 전역 어셈블리 캐시에 배포합시다. Windows7부터는 보안이 강화되어 관리자 권한으로 배포해야 합니다. 관리자 권한으로 Visual Studio 명령 프롬프트를 실행한 후에 gacutil /i demolib.dll 을 치면 배포가 됩니다.
[그림 1.9] gacutil 명령어로 전역 어셈블리 캐시에 배포
이제 배포한 공용 어셈블리를 사용하는 응용 프로그램 프로젝트를 생성하세요. 그리고 참조 추가를 통해 demolib.dll를 추가하세요. 전용 어셈블리에서 참조 추가하는 것과 같은 방법입니다.
전용 어셈블리를 참조 추가하면 자동으로 프로젝트 출력 폴더에 참조한 어셈블리 파일이 추가하지만 공용 어셈블리를 참조 추가하면 프로젝트 출력 폴더에 추가하지 않고 전역 어셈블리 캐시에 배포된 것을 사용합니다.
그리고 프로젝트 참조 폴더에 해당 어셈블리에 오른쪽 마우스 버튼을 클릭하여 컨텍스트 메뉴에서 속성을 선택하세요. 속성 창을 보면 특정 버전을 선택할 수 있습니다. 만약, 특정 버전 속성을 false로 설정하면 새로운 버전이 배포되면 자동으로 최신 버전을 사용합니다. 하지만 특정 버전 속성을 true로 설정하면 참조한 버전의 어셈블리를 사용하게 됩니다.
[그림 1.10] 특정 버전 속성 지정
여기서는 병행(Side by Side) 실행을 확인하기 위하여 특정 버전 속성을 True로 합시다. 그리고 사용하는 코드를 작성하여 빌드 후에 실행하세요.
▶ 공용 어셈블리(버전 1.0.0.0)를 사용하는 예제 코드
using DemoLib;
namespace UsingDemoV1 { class Program { static void Main(string[] args) { DemoClass dc = new DemoClass(); dc.Foo(); } } } |
▶ 실행 결과 Foo 1 |
그리고 DemoLib를 수정합시다. 조금 전에 만든 DemoLib를 사용하는 프로젝트는 닫아주세요.
▶ DemoLib (버전 1.0.0.1)
using System; namespace DemoLib { public class DemoClass { public void Foo() { Console.WriteLine("Foo 2"); } } } |
프로젝트 속성 창을 열어서 응용 프로그램 탭에 어셈블리 정보 버튼을 클릭합시다. 그리고 버전 정보를 수정하세요. 버전 정보를 수정하였으므로 조금 전에 만들어 배포한 어셈블리와 파일명과 확장자는 같지만 강력한 이름은 다릅니다. 전역 어셈블리 캐시에서는 강력한 이름으로 배포하기 때문에 재배포 가능합니다.
[그림 1.11] 어셈블리 버전 수정
프로젝트를 빌드한 후 gacutil 명령어를 이용하여 다시 배포합시다. 그리고 방금 만들었던 응용을 실행해서 참조한 버전의 어셈블리를 사용하고 있음을 확인하세요.
그리고 새로운 버전을 참조하여 사용하는 응용 프로그램을 작성해 보세요. 그리고 두 개의 응용 프로그램을 실행해 보시면 각각 자신이 참조하는 버전의 어셈블리를 사용함을 확인하실 수 있습니다.
1.5.5 문서 파일
이번에는 라이브러리를 만들 때 사용하는 곳에서 Microsoft Visual Studio의 인텔리센스 기능을 활용할 수 있게 해 봅시다.
프로젝트 속성 창에서 빌드 탭을 선택하여 XML 문서 파일을 체크하세요.
[그림 1.12] XML 문서 파일 출력 설정
그리고 빌드하면 공개한 멤버 형식에 주석이 없다는 경고 메시지가 나타납니다. XML 문서 파일 출력을 설정하면 가시성이 public인 형식과 멤버에 대한 세 줄 주석으로 XML 양식에 맞는 설명이 없으면 경고 메시지가 뜹니다. 다음과 같이 코드를 약간 변경한 후에 주석을 달아봅시다.
▶ XML 양식에 맞게 세 줄 주석 달기
using System;
namespace DemoLib { /// <summary> /// 데모 클래스 /// </summary> public class DemoClass { /// <summary> /// Foo 메서드 /// </summary> /// <param name="a">첫번째 인자 </param> /// <param name="b">두번째 인자 </param> /// <returns> 첫번째 인자 + 두번째 인자 </returns> public int Foo(int a,int b) { Console.WriteLine("a:{0} b:{1}",a,b); return a + b; } } } |
다시 빌드하시면 경고가 사라지고 출력 폴더에 가 보면 XML 파일이 생긴 것을 확인할 수 있습니다.
▶ XML 출력 파일 내용
<?xml version="1.0"?> <doc> <assembly> <name>DemoLib</name> </assembly> <members> <member name="T:DemoLib.DemoClass"> <summary> 데모 클래스 </summary> </member> <member name="M:DemoLib.DemoClass.Foo(System.Int32,System.Int32)"> <summary> Foo 메서드 </summary> <param name="a">첫 번째 인자</param> <param name="b">두 번째 인자</param> <returns> 첫 번째 인자 + 두 번째 인자</returns> </member> </members> </doc> |
그리고 콘솔 응용 프로그램을 생성한 후에 라이브러리를 참조 추가하고 천천히 Demo 형식의 개체를 생성하고 Foo 메서드를 호출하는 구문을 추가해 보세요. 다음처럼 인텔리센스 기능이 작동하여 메서드가 무엇을 의미하는지 인자가 무엇인지 설명하는 구문을 확인할 수 있습니다. 물론, 풍선 도움말에 나타나는 것은 XML 형식에 맞게 작성한 세 줄 주석에 작성한 내용입니다.
[그림 1.13] 인텔리센스 작동 화면
여러 명이 팀 작업을 할 때 이와 같은 기능은 많은 도움을 줍니다. 평소에도 XML 문서 출력 속성을 설정하여 세 줄 주석을 다는 것을 습관화하세요. 자신이 작성한 라이브러리도 사용하기 편하고 다른 동료도 여러분이 만든 라이브러리를 사용하기 편해질 것입니
'프로그래밍 기술 > 웹 검색 엔진 만들기' 카테고리의 다른 글
2. 요구 분석 및 정의 (0) | 2017.12.05 |
---|---|
1. 7 .NET 리모팅 (0) | 2017.12.05 |
1.6.2 사용자 정의 컨트롤 만들기 (0) | 2017.12.05 |
1.6.1 간단한 Windows Forms 응용 만들기 (0) | 2017.12.05 |
1. 6 Windows Form (0) | 2017.12.05 |
1. 5 라이브러리 (0) | 2017.11.09 |
1.3 시나리오 / 1.4 요구 기술 (0) | 2017.11.03 |
1. 2 개요 (0) | 2017.11.03 |
1. 1 검색 엔진 (0) | 2017.11.03 |
1. 검색 엔진 소개 및 개요 (0) | 2017.11.03 |