Microsoft MVP성태의 닷넷 이야기
.NET Framework: 842. .NET Reflection을 대체할 System.Reflection.Metadata 소개 [링크 복사], [링크+제목 복사],
조회: 21137
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

(시리즈 글이 11개 있습니다.)
.NET Framework: 404. 리플렉션을 이용해 닷넷 LicenseManager를 우회할 수 있는 사례
; https://www.sysnet.pe.kr/2/0/1565

.NET Framework: 428. .NET Reflection으로 다차원/Jagged 배열을 구분하는 방법
; https://www.sysnet.pe.kr/2/0/1653

.NET Framework: 537. C# - Reflection의 박싱 없이 값 형식을 다루는 방법
; https://www.sysnet.pe.kr/2/0/10866

.NET Framework: 685. C# - 구조체(값 형식)의 필드를 리플렉션을 이용해 값을 바꾸는 방법
; https://www.sysnet.pe.kr/2/0/11312

.NET Framework: 785. public으로 노출되지 않은 다른 어셈블리의 delegate 인스턴스를 Reflection으로 생성하는 방법
; https://www.sysnet.pe.kr/2/0/11583

.NET Framework: 842. .NET Reflection을 대체할 System.Reflection.Metadata 소개
; https://www.sysnet.pe.kr/2/0/11930

.NET Framework: 924. C# - Reflection으로 변경할 수 없는 readonly 정적 필드
; https://www.sysnet.pe.kr/2/0/12256

.NET Framework: 1045. C# - 런타임 시점에 이벤트 핸들러를 만들어 Reflection을 이용해 구독하는 방법
; https://www.sysnet.pe.kr/2/0/12609

.NET Framework: 1046. C# - 컴파일 시점에 참조할 수 없는 타입을 포함한 이벤트 핸들러를 Reflection을 이용해 구독하는 방법
; https://www.sysnet.pe.kr/2/0/12610

닷넷: 2155. C# - .NET 8 런타임부터 (Reflection 없이) 특성을 이용해 public이 아닌 멤버 호출 가능
; https://www.sysnet.pe.kr/2/0/13436

닷넷: 2249. C# - 부모의 필드/프로퍼티에 대해 서로 다른 자식 클래스 간에 Reflection 접근이 동작할까요?
; https://www.sysnet.pe.kr/2/0/13608




.NET Reflection을 대체할 System.Reflection.Metadata 소개

초기 .NET 1.x 시절에는 .NET DLL/EXE에 구현된 타입 정보를 알아보기 위해 Assembly.Load 메서드를 사용했는데요, 이때 해당 어셈블리가 로드되면 잠기는 문제가 발생하지만 어셈블리를 내리려면 AppDomain이 함께 내려가야 한다는 부작용으로 인해 이후 Assembly.ReflectionOnlyLoad 메서드가 나옵니다.

Assembly.ReflectionOnlyLoad
; https://learn.microsoft.com/en-us/dotnet/api/system.reflection.assembly.reflectiononlyload

이것은 어셈블리를 코드로써 로드하지 않고 메타데이터만 살펴볼 수 있도록 허용하므로 DLL/EXE가 잠기지 않는다는 장점이 있습니다. 그러던 것이, .NET Core가 나오면서 아예 순수 메타데이터 자체를 다룰 수 있도록 System.Reflection.Metadata가 나왔습니다. 이에 대해 검색해 보면 사용 예제가 하나 눈에 띄는데요,

Metadata Tools
; https://github.com/dotnet/metadata-tools

dotnet/metadata-tools
; https://github.com/dotnet/metadata-tools/blob/master/src/Microsoft.Metadata.Visualizer/MetadataVisualizer.cs

아쉽게도 .NET Framework 버전으로 나와 있는 데다 .NET Core에서는 일부 컴파일 오류가 발생해 직접 사용할 수가 없습니다. 그래서 ^^ 개인적으로 최대한 수정해 다음의 github 예제로 올렸습니다.

DotNetSamples/NetCore/Microsoft.Metadata.Visualizer/
; https://github.com/stjeong/DotNetSamples/tree/master/NetCore/Microsoft.Metadata.Visualizer

딱 하나, WriteForwarders를 못 옮겼는데요,

public void Visualize(int generation = -1)
{
    this.reader = (generation >= 0) ? readers[generation] : readers.Last();

    WriteModule();
    WriteTypeRef();
    WriteTypeDef();
    WriteField();
    WriteMethod();
    WriteParam();
    WriteMemberRef();
    WriteConstant();
    WriteCustomAttribute();
    WriteDeclSecurity();
    WriteStandAloneSig();
    WriteEvent();
    WriteProperty();
    WriteMethodImpl();
    WriteModuleRef();
    WriteTypeSpec();
    WriteEnCLog();
    WriteEnCMap();
    WriteAssembly();
    WriteAssemblyRef();
    WriteFile();
    //WriteForwarders();
    WriteExportedType();
    WriteManifestResource();
    WriteGenericParam();
    WriteMethodSpec();
    WriteGenericParamConstraint();

    WriteUserStrings();
    WriteStrings();
    WriteBlobs();
    WriteGuids();
}

나중에 기회 되면 손을 보겠습니다. ^^ 아니면 이 글을 읽으시는 분 중에 수정하셔서 PR 보내주셔도 좋겠고.




참고로 다음은 Microsoft.Metadata.Visualizer 예제 프로젝트를 이용해 스스로의 메타데이터를 출력한 결과입니다.

Microsoft.Metadata.Visualizer.dll
********************************************************************************
Module (0x00):
=====================================================================================================================
   Gen  Name                                        Mvid                                         EncId  EncBaseId
=====================================================================================================================
1: 0    'Microsoft.Metadata.Visualizer.dll' (#b10)  {5592d697-bdc0-4859-aced-22e20a3efaee} (#1)  nil    nil

TypeRef (0x01):
===================================================================================================================================
    Scope                     Name                                                   Namespace
===================================================================================================================================
 1: 0x23000001 (AssemblyRef)  'CompilationRelaxationsAttribute' (#921)               'System.Runtime.CompilerServices' (#11bf)
 2: 0x23000001 (AssemblyRef)  'RuntimeCompatibilityAttribute' (#987)                 'System.Runtime.CompilerServices' (#11bf)
 3: 0x23000001 (AssemblyRef)  'DebuggableAttribute' (#853)                           'System.Diagnostics' (#1185)
 4: 0x01000003 (TypeRef)      'DebuggingModes' (#1234)                               nil
 5: 0x23000001 (AssemblyRef)  'TargetFrameworkAttribute' (#87e)                      'System.Runtime.Versioning' (#a81)
...[생략]...
99: 0x23000002 (AssemblyRef)  'Stream' (#b46)                                        'System.IO' (#22a)
9a: 0x23000003 (AssemblyRef)  'PEReaderExtensions' (#1444)                           'System.Reflection.Metadata' (#236)
9b: 0x23000001 (AssemblyRef)  'Enum' (#bbc)                                          'System' (#b89)
9c: 0x23000001 (AssemblyRef)  'StringComparison' (#f98)                              'System' (#b89)

TypeDef (0x02):
=================================================================================================================================================================================================================================================================================================================
   Name                           Namespace                                EnclosingType         BaseType              Interfaces  Fields                 Methods                Attributes                                                                                       ClassSize  PackingSize
=================================================================================================================================================================================================================================================================================================================
1: '<Module>' (#221)              nil                                      nil                   nil                   nil         nil                    nil                    0                                                                                                0          0
2: 'MetadataVisualizer' (#10e5)   'Microsoft.Metadata.Visualizer' (#10c7)  nil                   0x0100000c (TypeRef)  nil         0x04000001-0x04000006  0x06000001-0x06000035  0x00100101 (AutoLayout, AnsiClass, Class, Public, Sealed, BeforeFieldInit)                       0          0
3: 'Program' (#b6a)               'Microsoft.Metadata.Visualizer' (#10c7)  nil                   0x0100000c (TypeRef)  nil         nil                    0x06000036-0x06000038  0x00100000 (AutoLayout, AnsiClass, Class, BeforeFieldInit)                                       0          0
4: 'TokenTypeComparer' (#1033)    nil                                      0x02000002 (TypeDef)  0x0100000c (TypeRef)  0x09000001  0x04000007-0x04000007  0x06000039-0x0600003b  0x00100103 (AutoLayout, AnsiClass, Class, NestedPrivate, Sealed, BeforeFieldInit)                0          0
5: '<>c' (#272)                   nil                                      0x02000002 (TypeDef)  0x0100000c (TypeRef)  nil         0x04000008-0x04000012  0x0600003c-0x06000047  0x00102103 (AutoLayout, AnsiClass, Class, NestedPrivate, Sealed, Serializable, BeforeFieldInit)  0          0
6: '<>c__DisplayClass29_0' (#fd)  nil                                      0x02000002 (TypeDef)  0x0100000c (TypeRef)  nil         0x04000013-0x04000014  0x06000048-0x06000049  0x00100103 (AutoLayout, AnsiClass, Class, NestedPrivate, Sealed, BeforeFieldInit)                0          0
7: '<>c__DisplayClass0_0' (#1c)   nil                                      0x02000003 (TypeDef)  0x0100000c (TypeRef)  nil         0x04000015-0x04000015  0x0600004a-0x0600004b  0x00100103 (AutoLayout, AnsiClass, Class, NestedPrivate, Sealed, BeforeFieldInit)                0          0

Field (0x04):
================================================================================================================================================
    Name                   Signature                                         Attributes                             Marshalling  Offset  RVA
================================================================================================================================================
 1: 'writer' (#108a)       06-12-35 (#8d5)                                   0x00000021 (Private, InitOnly)         nil          n/a     0
 2: 'readers' (#152b)      06-15-12-39-01-12-3D (#8d9)                       0x00000021 (Private, InitOnly)         nil          n/a     0
 3: 'aggregator' (#111f)   06-12-41 (#8e1)                                   0x00000021 (Private, InitOnly)         nil          n/a     0
...[생략]...
13: '<>4__this' (#140a)    06-12-08 (#95b)                                   0x00000006 (Public)                    nil          n/a     0
14: 'displayTable' (#425)  06-02 (#95f)                                      0x00000006 (Public)                    nil          n/a     0
15: 'args' (#1405)         06-1D-0E (#962)                                   0x00000006 (Public)                    nil          n/a     0

Method (0x06, 0x1C):
=======================================================================================================================================================================================================================================================================================================================
    Name                                   Signature                                                        RVA         Parameters             GenericParameters      ImplAttributes                                                                     Attributes  ImportAttributes  ImportName  ImportModule
=======================================================================================================================================================================================================================================================================================================================
 1: '.ctor' (#1144)                        20-02-01-12-35-15-12-39-01-12-3D (#966)                          0x00002050  0x08000001-0x08000002  nil                    0x00001881 (PrivateScope, Private, HideBySig, SpecialName, RTSpecialName)          0           0                 nil         nil
 2: '.ctor' (#1144)                        20-02-01-12-3D-12-35 (#972)                                      0x000020DD  0x08000003-0x08000004  nil                    0x00001886 (PrivateScope, Public, HideBySig, SpecialName, RTSpecialName)           0           0                 nil         nil
 3: '.ctor' (#1144)                        20-02-01-15-12-39-01-12-3D-12-35 (#97a)                          0x000020F9  0x08000005-0x08000006  nil                    0x00001886 (PrivateScope, Public, HideBySig, SpecialName, RTSpecialName)           0           0                 nil         nil
 4: 'VisualizeAllGenerations' (#1470)      20-00-01 (#6)                                                    0x00002108  nil                    nil                    0x00000086 (PrivateScope, Public, HideBySig)                                       0           0                 nil         nil
...[생략]...
49: '<TokenList>b__0' (#11e)               20-01-0E-11-80-89 (#a55)                                         0x0000487A  0x08000033-0x08000033  nil                    0x00000083 (PrivateScope, Assembly, HideBySig)                                     0           0                 nil         nil
4a: '.ctor' (#1144)                        20-00-01 (#6)                                                    0x00004893  nil                    nil                    0x00001886 (PrivateScope, Public, HideBySig, SpecialName, RTSpecialName)           0           0                 nil         nil
4b: '<Main>b__0' (#113)                    20-01-02-0E (#a5c)                                               0x0000489C  0x08000034-0x08000034  nil                    0x00000083 (PrivateScope, Assembly, HideBySig)                                     0           0                 nil         nil

Param (0x08):
=====================================================================================
    Name                       Seq#  Attributes                         Marshalling
=====================================================================================
 1: 'writer' (#108a)           1     0                                  nil
 2: 'readers' (#152b)          2     0                                  nil
...[생략]...
31: 'h' (#afc)                 1     0                                  nil
32: 'h' (#afc)                 1     0                                  nil
33: 'h' (#afc)                 1     0                                  nil
34: 'x' (#1781)                1     0                                  nil

MemberRef (0x0a):
============================================================================================================================================================
     Parent                 Name                                         Signature
============================================================================================================================================================
  1: 0x01000001 (TypeRef)   '.ctor' (#1144)                              20-01-01-08 (#1)
  2: 0x01000002 (TypeRef)   '.ctor' (#1144)                              20-00-01 (#6)
  3: 0x01000003 (TypeRef)   '.ctor' (#1144)                              20-01-01-11-11 (#a)
...[생략]...
13d: 0x01000022 (TypeRef)   'op_Implicit' (#1633)                        00-01-11-49-11-80-89 (#8b2)
13e: 0x01000072 (TypeRef)   'Equals' (#1414)                             00-03-02-0E-0E-11-82-71 (#8ba)

Constant (0x0b):
=================================================================
   Parent              Type                  Value
=================================================================
1: 0x08000007 (Param)  0x00000008 (Int32)    FF-FF-FF-FF (#8cc)
2: 0x0800001c (Param)  0x00000002 (Boolean)  01 (#8d1)
3: 0x08000021 (Param)  0x00000002 (Boolean)  00 (#8d3)

CustomAttribute (0x0c):
=========================================================================================================================================================================================================================
    Parent                 Constructor             Value
=========================================================================================================================================================================================================================
 1: 0x20000001 (Assembly)  0x0a000001 (MemberRef)  01-00-08-00-00-00-00-00 (#a65)
 2: 0x20000001 (Assembly)  0x0a000002 (MemberRef)  01-00-01-00-54-02-16-57-72-61-70-4E-6F-6E-45-78-63-65-70-74-69-6F-6E-54-68-72-6F-77-73-01 (#a6e)
...[생략]...
 d: 0x02000007 (TypeDef)   0x0a00000c (MemberRef)  01-00-00-00 (#b12)
 e: 0x08000008 (Param)     0x0a00000b (MemberRef)  01-00-00-00 (#b12)
 f: 0x08000009 (Param)     0x0a00000b (MemberRef)  01-00-00-00 (#b12)

StandAloneSig (0x11):
===================================================================================================
    Signature
===================================================================================================
 1: 07-02-02-15-12-4D-01-12-3D (#24)
 2: 07-02-08-02 (#d7)
 3: 07-01-02 (#ef)
...[생략]...
2b: 07-0A-12-1C-02-1D-0E-08-0E-12-81-B1-12-81-B5-12-3D-12-08-12-81-B9 (#80f)
2c: 07-02-11-5D-08 (#866)

Property (0x15, 0x17, 0x18):
===============================================================
   Name              Get                     Set  Attributes
===============================================================
1: 'IsDelta' (#26a)  0x06000006 (MethodDef)  nil  0

TypeSpec (0x1b):
===============================================
    Name
===============================================
 1: 15-12-79-01-1E-00 (#15)
 2: 15-12-81-9D-01-11-49 (#1c)
...[생략]...
19: 15-12-80-81-02-11-81-AD-11-49 (#726)
1a: 15-12-80-81-02-0E-02 (#826)

Assembly (0x20):
======================================================================================================
   Name                                     Version  Culture  PublicKey  Flags  HashAlgorithm
======================================================================================================
1: 'Microsoft.Metadata.Visualizer' (#10c7)  1.0.0.0  nil      nil        0      0x00008004 (Sha1)

AssemblyRef (0x23):
=======================================================================================================
   Name                                    Version   Culture  PublicKeyOrToken                Flags
=======================================================================================================
1: 'System.Runtime' (#780)                 4.1.0.0   nil      B0-3F-5F-7F-11-D5-0A-3A (#8c3)  0
2: 'System.IO' (#22a)                      4.1.0.0   nil      B0-3F-5F-7F-11-D5-0A-3A (#8c3)  0
3: 'System.Reflection.Metadata' (#236)     1.3.0.0   nil      B0-3F-5F-7F-11-D5-0A-3A (#8c3)  0
...[생략]...
a: 'System.Reflection.Primitives' (#13b2)  4.0.0.0   nil      B0-3F-5F-7F-11-D5-0A-3A (#8c3)  0
b: 'System.Console' (#74b)                 4.0.0.0   nil      B0-3F-5F-7F-11-D5-0A-3A (#8c3)  0

GenericParam (0x2a):
================================================================
   Name               Seq#  Attributes  TypeConstraints
================================================================
1: 'TEntity' (#17fa)  0     0           nil
2: 'T' (#234)         0     0           0x2c000001-0x2c000001
3: 'THandle' (#48b)   0     0           nil

MethodSpec (0x2b):
===============================================================
    Method                  Signature
===============================================================
 1: 0x0a000010 (MemberRef)  0A-01-12-3D (#53)
 2: 0x0a000015 (MemberRef)  0A-02-12-3D-15-11-45-01-11-49 (#b2)
 3: 0x0a000016 (MemberRef)  0A-01-15-11-45-01-11-49 (#ce)
 4: 0x0a00001a (MemberRef)  0A-01-12-3D (#53)
 5: 0x0a00001a (MemberRef)  0A-01-1D-0E (#106)
...[생략]...
13: 0x06000016 (MethodDef)  0A-01-11-81-AD (#731)
14: 0x0a00012c (MemberRef)  0A-01-0E (#842)
15: 0x0a000016 (MemberRef)  0A-01-11-49 (#1cd)

GenericParamConstraint (0x2c):
====================================================
   Parent                     Type
====================================================
1: 0x2a000002 (GenericParam)  0x1b000001 (TypeSpec)

#US (size = 2816):
  0: ''
  1: '>>>'
  9: '>>> Generation {0}:'
  31: '  '
  37: 'x'
  3b: ': '
...[생략]...
  af2: '''
  af6: '{'
  afa: '}'
  afe: ''
  aff: ''

#String (size = 6160):
  0: ''
  1: '<>9__20_0'
  b: '<Literal>b__20_0'
  1c: '<>c__DisplayClass0_0'
  31: '<>9__21_0'
  3b: '<Literal>b__21_0'
...[생략]...
  17cc: 'Any'
  17d0: 'EditAndContinueLogEntry'
  17e8: 'WriteDeclSecurity'
  17fa: 'TEntity'
  1802: 'WriteProperty'

#Blob (size = 2840):
  0:
  1: 20-01-01-08
  6: 20-00-01
  a: 20-01-01-11-11
  10: 20-01-01-0E
  15: 15-12-79-01-1E-00
  1c: 15-12-81-9D-01-11-49
  24: 07-02-02-15-12-4D-01-12-3D
...[생략]...
  afa: 01-00-07-31-2E-30-2E-30-2E-30-00-00
  b07: 01-00-05-31-2E-30-2E-30-00-00
  b12: 01-00-00-00
  b17:

#Guid (size = 16):
  1: {5592d697-bdc0-4859-aced-22e20a3efaee}




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 11/7/2023]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2020-08-01 10시46분
[이동우] 우연찮게 둘렀다가 잘보고갑니답!
[guest]

... 121  122  123  124  125  126  127  128  129  130  131  132  133  [134]  135  ...
NoWriterDateCnt.TitleFile(s)
1739정성태8/24/201427808.NET Framework: 457. 교착상태(Dead-lock) 해결 방법 - Lock Leveling [2]파일 다운로드1
1738정성태8/23/201423457.NET Framework: 456. C# - CAS를 이용한 Lock 래퍼 클래스파일 다운로드1
1737정성태8/20/201420942VS.NET IDE: 93. Visual Studio 2013 동기화 문제
1736정성태8/19/201426926VC++: 79. [부연] CAS Lock 알고리즘은 과연 빠른가? [2]파일 다운로드1
1735정성태8/19/201419491.NET Framework: 455. 닷넷 사용자 정의 예외 클래스의 최소 구현 코드 - 두 번째 이야기
1734정성태8/13/201421252오류 유형: 237. Windows Media Player cannot access the file. The file might be in use, you might not have access to the computer where the file is stored, or your proxy settings might not be correct.
1733정성태8/13/201427528.NET Framework: 454. EmptyWorkingSet Win32 API를 사용하는 C# 예제파일 다운로드1
1732정성태8/13/201435852Windows: 99. INetCache 폴더가 다르게 보이는 이유
1731정성태8/11/201428317개발 환경 구성: 235. 점(.)으로 시작하는 파일명을 탐색기에서 만드는 방법
1730정성태8/11/201423497개발 환경 구성: 234. Royal TS의 터미널(Terminal) 연결에서 한글이 깨지는 현상 해결 방법
1729정성태8/11/201419499오류 유형: 236. SqlConnection - The requested Performance Counter is not a custom counter, it has to be initialized as ReadOnly.
1728정성태8/8/201431729.NET Framework: 453. C# - 오피스 파워포인트(Powerpoint) 파일을 WinForm에서 보는 방법파일 다운로드1
1727정성태8/6/201421933오류 유형: 235. SignalR 오류 메시지 - Counter 'Messages Bus Messages Published Total' does not exist in the specified Category. [2]
1726정성태8/6/201420715오류 유형: 234. IIS Express에서 COM+ 사용 시 SecurityException - "Requested registry access is not allowed" 발생
1725정성태8/6/201422668오류 유형: 233. Visual Studio 2013 Update3 적용 후 Microsoft.VisualStudio.Web.PageInspector.Runtime 모듈에 대한 FileNotFoundException 예외 발생
1724정성태8/5/201427461.NET Framework: 452. .NET System.Threading.Thread 개체에서 Native Thread Id를 구하는 방법 - 두 번째 이야기 [1]파일 다운로드1
1723정성태7/29/201459875개발 환경 구성: 233. DirectX 9 예제 프로젝트 빌드하는 방법 [3]파일 다운로드1
1722정성태7/25/201422239오류 유형: 232. IIS 500 Internal Server Error - NTFS 암호화된 폴더에 웹 애플리케이션이 위치한 경우
1721정성태7/24/201425539.NET Framework: 451. 함수형 프로그래밍 개념 - 리스트 해석(List Comprehension)과 순수 함수 [2]
1720정성태7/23/201423480개발 환경 구성: 232. C:\WINDOWS\system32\LogFiles\HTTPERR 폴더에 로그 파일을 남기지 않는 설정
1719정성태7/22/201427388Math: 13. 동전을 여러 더미로 나누는 경우의 수 세기(Partition Number) - 두 번째 이야기파일 다운로드1
1718정성태7/19/201436838Math: 12. HTML에서 수학 관련 기호/수식을 표현하기 위한 방법 - MathJax.js [4]
1716정성태7/17/201436510개발 환경 구성: 231. PC 용 무료 안드로이드 에뮬레이터 - genymotion
1715정성태7/13/201431611기타: 47. 운영체제 종료 후에도 USB 외장 하드의 전원이 꺼지지 않는 경우 [3]
1714정성태7/11/201421574VS.NET IDE: 92. Visual Studio 2013을 지원하는 IL Support 확장 도구
1713정성태7/11/201445357Windows: 98. 윈도우 시스템 디스크 용량 확보를 위한 "Package Cache" 폴더 이동 [1]
... 121  122  123  124  125  126  127  128  129  130  131  132  133  [134]  135  ...