다음을 통해 공유


메타데이터 저장소

업데이트: 2007년 11월

Windows Presentation Foundation(WPF) Designer for Visual Studio 프레임워크에서는 디자인 타임 메타데이터가 구현과 분리됩니다. 메타데이터를 런타임 코드와 분리하는 것은 디자인 측면에서 중요한 원칙이며 그 이유는 다음과 같습니다.

  • 팀 간에 순환 및 통합 논리를 구축할 경우 메타데이터를 프레임워크 코드에 컴파일하는 작업이 번거로워질 수 있습니다.

  • 메타데이터를 런타임 코드에 컴파일하면 WPF Designer 또는 Expression Blend와 같은 외부 도구가 나중에 메타데이터를 수정할 수 없습니다. 이는 신속성의 측면에서 문제가 됩니다. 디자인 타임 메타데이터를 코드와 분리하지 않을 경우 Visual Studio에서 해당 디자이너의 버전을 관리하려면 .NET Framework의 새 버전이 있어야 합니다.

  • 메타데이터를 런타임에 컴파일하면 런타임 어셈블리의 크기가 대폭 커집니다. 또한 디자인 타임 특성도 런타임을 느리게 만듭니다. 리플렉션을 사용하는 데이터 바인딩과 같은 런타임 기능의 경우 추가 특성이 메모리에 로드될 때 영향을 받습니다.

  • 디자인 타임 메타데이터는 디자이너의 "특성(personality)"을 제공합니다. 디자이너의 기능은 런타임이 아니라 디자이너를 호스팅하는 응용 프로그램과 대부분 연결됩니다. WPF Designer 및 Expression Blend에서는 다양한 메타데이터 집합을 사용하여 특정 사용자층을 대상으로 하는 기능 집합을 제공합니다.

메타데이터 저장소

메타데이터 저장소는 디자인 타임 메타데이터가 저장되는 위치입니다. 메타데이터 저장소용 API는 단순합니다. AddAttributeTable 메서드를 호출하여 메타데이터 특성 테이블을 추가합니다. 메타데이터 저장소에 테이블이 추가되면 TypeDescriptor 쿼리를 통해 해당 테이블에 정의된 특성을 사용할 수 있습니다. 이미 쿼리된 형식에 대한 추가 특성이 테이블에 포함되어 있으면 형식의 메타데이터가 변경되었음을 보고하기 위해 Refreshed 이벤트가 발생합니다.

특성 테이블

특성 테이블은 기본적으로 읽기 전용 사전이지만 키와 값이 개별적으로 계산됩니다. 특정 형식에 대한 특성을 보려면 특성 테이블을 쿼리하는 것이 효율적입니다. 실제 특성 집합은 요청 시 만들어집니다. 특정 형식에 대한 사용자 지정 메타데이터를 검색하려면 GetCustomAttributes 메서드를 호출합니다.

특성 테이블은 형식의 속성만 지원하고 필드나 메서드의 특성은 지원하지 않습니다.

특성 테이블 작성기

특성 테이블을 만들려면 우선 AttributeTableBuilder 클래스의 인스턴스를 만듭니다. 그런 다음 AddCustomAttributes 오버로드를 호출하여 특성 테이블 작성기에 메타데이터를 추가합니다. 메타데이터 추가를 마친 후에는 CreateTable 메서드를 호출하여 특성 테이블 작성기에서 특성 테이블을 만듭니다. 특성 테이블 작성기 메서드는 콜백 대리자를 지원하므로 필요할 때까지 특성 테이블 생성을 지연시킬 수 있습니다.

사용자 지정 특성 만들기

메타데이터 저장소는 사용자 지정 특성이 해당 TypeId 속성에 대해 올바르게 정의된 재정의를 갖는다는 사실에 기반을 둡니다. 메타데이터 저장소는 TypeId 속성을 통해 형식이 같거나 다른 두 특성을 동일한 인스턴스로 처리해야 할지 여부를 결정합니다.

기본 Attribute 클래스가 다음과 같이 TypeId 속성을 정의합니다.

    public class Attribute
    {
        ...

        public virtual object TypeId
        {
            get
            {
                return base.GetType();
            }
        }

        ...
    }

이 구현에서는 같은 Attribute 형식의 두 인스턴스가 동일한 특성으로 나타납니다. 인스턴스 중 하나는 기본 TypeDescriptor 구현에서 무시합니다. FeatureAttribute 클래스를 사용할 때와 마찬가지로 사용자 지정 특성의 이 동작을 사용하지 않으려는 경우, 각 형식 인스턴스에 대해 고유한 개체를 반환하도록 사용자 지정 특성으로 TypeId 속성을 재정의해야 합니다. 예를 들어, FeatureAttribute 클래스는 다음 코드를 사용하여 TypeId 속성을 재정의합니다.

public override object TypeId
{
    get { return this; }
}

this는 각 개체 인스턴스에 대한 고유한 개체를 나타내므로 FeatureAttribute는 같은 클래스를 안전하게 여러 번 데코레이팅할 수 있으며 메타데이터 저장소와 함께 사용될 경우 원하는 결과를 생성할 수 있습니다.

메타데이터 어셈블리 명명 규칙

디자인 타임 코드는 특수 메타데이터 어셈블리에 배포됩니다. 모든 디자이너에서 지원되는 디자인 타임 기능은 기본 라이브러리 이름 뒤에 ".Design"이 추가된 어셈블리에 배포됩니다. Visual Studio에서만 지원되는 디자인 타임 기능은 기본 라이브러리 이름 뒤에 ".VisualStudio.Design"이 추가된 어셈블리에 배포됩니다. 다음 표에서는 CustomControlLibrary.dll이라는 런타임 컨트롤 라이브러리의 이름을 예로 보여 줍니다.

디자이너

디자인 타임 어셈블리 이름

Visual Studio에서만 지원되는 경우

CustomControlLibrary.VisualStudio.Design.dll

Expression Blend에서만 지원되는 경우

CustomControlLibrary.Expression.Design.dll

모든 디자이너에서 지원되는 경우

CustomControlLibrary.Design.dll

메타데이터 어셈블리 로드

디자이너가 런타임 어셈블리를 로드할 때 해당 메타데이터 어셈블리도 검색합니다. 해당 메타데이터 어셈블리가 있으면 런타임 어셈블리가 로드된 후 곧바로 로드됩니다.

프로젝트에 대한 새 어셈블리 참조를 추가하면 해당 메타데이터 어셈블리를 모두 검색하여 있으면 로드됩니다.

메타데이터 어셈블리를 다시 빌드하면 다시 로드됩니다.

참고:

*.Design.dll 메타데이터 어셈블리는 특정 디자이너의 *.VisualStudio.Design.dll 및 *.Expression.Design.dll 어셈블리보다 먼저 로드됩니다. 디자이너 고유의 메타데이터는 공유 메타데이터를 재정의합니다.

메타데이터 어셈블리 검색 순서

프로젝트에서 직접 참조하는 어셈블리에는 다음 검색 순서가 적용됩니다.

  1. 디자이너가 참조된 런타임 어셈블리와 동일한 폴더를 검색합니다. 이 위치는 빌드에서 어셈블리를 찾기 위해 사용하는 것과 같은 알고리즘을 사용하여 찾으며 SDK 폴더와 추가 경로를 검색하는 것이 포함됩니다.

  2. 디자이너가 컨트롤의 런타임 어셈블리가 있는 폴더에서 "Design" 하위 폴더를 찾습니다.

컨트롤의 런타임 어셈블리를 GAC(전역 어셈블리 캐시)에서 로드할 수도 있지만 참조는 항상 GAC 외부의 위치를 가리킵니다. 대개 이 위치는 SDK 폴더 내입니다. WPF Designer에서 Visual Studio API를 사용하여 파일 시스템에서 참조된 어셈블리를 찾습니다. 프로젝트 HintPath가 지정되지 않은 경우에도 해당됩니다. 디자이너가 컨트롤의 런타임 어셈블리가 로드된 위치가 아니라 컨트롤의 런타임 어셈블리가 참조된 위치에서 메타데이터 어셈블리를 로드하려고 합니다.

간접적으로 참조된 어셈블리가 로드됩니다. 간접적으로 참조된 어셈블리는 프로젝트에서 참조하는 어셈블리에서 참조하기 때문입니다. 예를 들어 MyAssembly라는 어셈블리에 대한 참조를 포함하는 프로젝트가 있고 MyAssembly에 프로젝트에서 직접 참조하지 않는 MyOtherAssembly에 대한 참조가 있는 경우 MyOtherAssembly는 간접적으로 참조된 것으로 간주됩니다.

이러한 경우 이 어셈블리는 빌드에 필요하지 않으며 빌드 시스템은 간접적으로 참조된 어셈블리의 위치를 파일 시스템에서 찾지 않습니다. 다음 표에서는 디자이너가 간접적으로 참조된 어셈블리를 로드하는 방법을 보여 줍니다.

참조된 어셈블리

검색 순서

GAC에서 로드된 파일

SDK 폴더에서 해당 메타데이터 어셈블리를 검색합니다. 이 어셈블리가 있으면 해당 경로 및 "Design" 하위 폴더에서 해당 메타데이터 어셈블리를 검색합니다.

GAC 외부의 위치에서 로드된 파일

런타임 어셈블리의 경로 및 해당 "Design" 하위 폴더에서 해당 메타데이터 어셈블리를 검색합니다.

IRegisterMetadata 구현 찾기

메타데이터 어셈블리에는 IRegisterMetadata 인터페이스에 대한 구현이 하나 이상 포함되어 있어야 합니다. IRegisterMetadata 구현은 리플렉션을 사용하여 찾습니다. 어셈블리에 IRegisterMetadata 구현이 여러 개 있으면 각 구현이 인스턴스화되어 리플렉션 API에서 반환한 순서대로 호출됩니다.

참고 항목

참조

Microsoft.Windows.Design.Metadata

MetadataStore

AttributeTable

AttributeTableBuilder

FeatureAttribute

기타 리소스

WPF Designer 확장성