Microsoft MVP성태의 닷넷 이야기
글쓴 사람
홈페이지
첨부 파일
 

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

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

Assembly.ReflectionOnlyLoad
; https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.reflectiononlyload?view=netframework-4.8

이것은 어셈블리를 코드로써 로드하지 않고 메타데이터만 살펴볼 수 있도록 허용하므로 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}




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





[최초 등록일: ]
[최종 수정일: 6/26/2019 ]

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

비밀번호

댓글 쓴 사람
 




1  2  3  [4]  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
11950정성태6/18/2019521.NET Framework: 845. C# - 윈도우 작업 관리자와 리소스 모니터의 메모리 값을 구하는 방법
11949정성태6/18/2019312오류 유형: 547. CoreCLR Profiler 예제 프로젝트 빌드 시 컴파일 오류 유형
11948정성태6/17/2019394Linux: 15. 리눅스 환경의 Visual Studio Code에서 TFS 서버 연동
11947정성태6/17/2019459Linux: 14. 리눅스 환경에서 TFS 서버 연동
11946정성태6/17/2019476개발 환경 구성: 445. C# - MathNet으로 정규 분포를 따르는 데이터를 생성, PLplot으로 Histogram 표현파일 다운로드1
11945정성태6/25/2019462Linux: 13. node.js에서 syslog로 출력하는 방법
11944정성태6/16/2019707Linux: 12. Ubuntu 16.04/18.04에서 node.js 최신 버전 설치 방법
11943정성태6/15/2019715.NET Framework: 844. C# - 박싱과 언박싱 [1]
11942정성태6/20/2019938개발 환경 구성: 444. 로컬의 Visual Studio Code로 원격 리눅스 머신에 접속해 개발하는 방법
11941정성태6/13/2019417오류 유형: 546. "message NETSDK1057: You are using a preview version of .NET Core" 빌드 경고 없애는 방법
11940정성태6/13/2019391개발 환경 구성: 443. Visual Studio의 Connection Manager 기능(Remote SSH 관리)을 위한 명령행 도구파일 다운로드1
11939정성태6/13/2019330오류 유형: 545. Managed Debugging Assistant 'FatalExecutionEngineError'
11938정성태6/12/2019488Math: 59. C# - 웨이트 벡터 갱신식을 이용한 퍼셉트론 분류파일 다운로드1
11937정성태6/11/20191356개발 환경 구성: 442. .NET Core 3.0 preview 5를 이용해 Windows Forms/WPF 응용 프로그램 개발 [1]
11936정성태6/10/2019501Math: 58. C# - 최소 자승법의 1차, 2차 수렴 그래프 변화 확인파일 다운로드1
11935정성태6/9/2019576.NET Framework: 843. C# - PLplot 출력을 파일이 아닌 Window 화면으로 변경
11934정성태6/7/2019474VC++: 133. typedef struct와 타입 전방 선언으로 인한 C2371 오류파일 다운로드1
11933정성태6/7/2019581VC++: 132. enum 정의를 C++11의 enum class로 바꿀 때 유의할 사항파일 다운로드1
11932정성태6/7/2019480오류 유형: 544. C++ - fatal error C1017: invalid integer constant expression파일 다운로드1
11931정성태6/6/2019519개발 환경 구성: 441. C# - CairoSharp/GtkSharp 사용을 위한 프로젝트 구성 방법
11930정성태6/26/2019700.NET Framework: 842. .NET Reflection을 대체할 System.Reflection.Metadata 소개
11929정성태6/5/2019508.NET Framework: 841. Windows Forms/C# - 클립보드에 RTF 텍스트를 복사 및 확인하는 방법
11928정성태6/5/2019620오류 유형: 543. PowerShell 확장 설치 시 "Catalog file '[...].cat' is not found in the contents of the module" 오류 발생
11927정성태6/5/2019701스크립트: 15. PowerShell ISE의 스크립트를 복사 후 PPT/Word에 붙여 넣으면 한글이 깨지는 문제 [1]
11926정성태6/4/2019567오류 유형: 542. Visual Studio - pointer to incomplete class type is not allowed
11925정성태6/4/2019678VC++: 131. Visual C++ - uuid 확장 속성과 __uuidof 확장 연산자파일 다운로드1
1  2  3  [4]  5  6  7  8  9  10  11  12  13  14  15  ...