Added a sample about Reflection

ci
Marc CHEVALDONNE 6 years ago
parent 5ef1a58359
commit 6fdc410a41

@ -459,7 +459,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ex_008_005_pattern_matching
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ex_014_008_deconstruction", "ex_014_008_deconstruction\ex_014_008_deconstruction.csproj", "{33CE1C87-3C57-48B8-A96E-FBF048BE65B8}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ex_014_008_deconstruction", "ex_014_008_deconstruction\ex_014_008_deconstruction.csproj", "{33CE1C87-3C57-48B8-A96E-FBF048BE65B8}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ex_016_006_local_functions", "ex_016_006_local_functions\ex_016_006_local_functions.csproj", "{C67D6972-67D5-4AB8-84FA-CF7F8C7BD3E6}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ex_016_006_local_functions", "ex_016_006_local_functions\ex_016_006_local_functions.csproj", "{C67D6972-67D5-4AB8-84FA-CF7F8C7BD3E6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "chap036_Reflection", "chap036_Reflection", "{CC07C89A-B410-4112-8686-A297FC0D34A8}"
ProjectSection(SolutionItems) = preProject
ex_036_001_Reflection\README.md = ex_036_001_Reflection\README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Applications", "Applications", "{3DE71730-143F-4835-A6B3-E501910EA94C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ex_036_001_Mammifere", "ex_036_001_Reflection\Solution\MammifereDll\ex_036_001_Mammifere.csproj", "{08D87D16-A9ED-42BC-8AF5-31AF9999AEF2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ex_036_001_ChatChienOiseau", "ex_036_001_Reflection\Solution\ChatChienOiseauDll\ex_036_001_ChatChienOiseau.csproj", "{FAA3150B-7230-4578-8CC0-775EDE947E7D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ex_036_001_Reflection", "ex_036_001_Reflection\Solution\Applications\ex_036_001_Reflection.csproj", "{3F4AF8F0-63C2-4226-BA8C-3D9992EB59C5}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -1147,6 +1160,18 @@ Global
{C67D6972-67D5-4AB8-84FA-CF7F8C7BD3E6}.Debug|Any CPU.Build.0 = Debug|Any CPU {C67D6972-67D5-4AB8-84FA-CF7F8C7BD3E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C67D6972-67D5-4AB8-84FA-CF7F8C7BD3E6}.Release|Any CPU.ActiveCfg = Release|Any CPU {C67D6972-67D5-4AB8-84FA-CF7F8C7BD3E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C67D6972-67D5-4AB8-84FA-CF7F8C7BD3E6}.Release|Any CPU.Build.0 = Release|Any CPU {C67D6972-67D5-4AB8-84FA-CF7F8C7BD3E6}.Release|Any CPU.Build.0 = Release|Any CPU
{08D87D16-A9ED-42BC-8AF5-31AF9999AEF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08D87D16-A9ED-42BC-8AF5-31AF9999AEF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08D87D16-A9ED-42BC-8AF5-31AF9999AEF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08D87D16-A9ED-42BC-8AF5-31AF9999AEF2}.Release|Any CPU.Build.0 = Release|Any CPU
{FAA3150B-7230-4578-8CC0-775EDE947E7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FAA3150B-7230-4578-8CC0-775EDE947E7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FAA3150B-7230-4578-8CC0-775EDE947E7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FAA3150B-7230-4578-8CC0-775EDE947E7D}.Release|Any CPU.Build.0 = Release|Any CPU
{3F4AF8F0-63C2-4226-BA8C-3D9992EB59C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F4AF8F0-63C2-4226-BA8C-3D9992EB59C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F4AF8F0-63C2-4226-BA8C-3D9992EB59C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F4AF8F0-63C2-4226-BA8C-3D9992EB59C5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -1370,6 +1395,11 @@ Global
{D1C02BFB-DA1E-4E9C-8236-BF5CC3C23F06} = {F2776023-5053-4F3A-895B-149456580FAD} {D1C02BFB-DA1E-4E9C-8236-BF5CC3C23F06} = {F2776023-5053-4F3A-895B-149456580FAD}
{33CE1C87-3C57-48B8-A96E-FBF048BE65B8} = {7B8E3B4B-5E02-460A-98B4-C948F6CD61F0} {33CE1C87-3C57-48B8-A96E-FBF048BE65B8} = {7B8E3B4B-5E02-460A-98B4-C948F6CD61F0}
{C67D6972-67D5-4AB8-84FA-CF7F8C7BD3E6} = {3469E317-6219-492E-98CF-B291CC4F4577} {C67D6972-67D5-4AB8-84FA-CF7F8C7BD3E6} = {3469E317-6219-492E-98CF-B291CC4F4577}
{CC07C89A-B410-4112-8686-A297FC0D34A8} = {7C341E9D-52D0-43EB-BE40-3807F4D86FA6}
{3DE71730-143F-4835-A6B3-E501910EA94C} = {CC07C89A-B410-4112-8686-A297FC0D34A8}
{08D87D16-A9ED-42BC-8AF5-31AF9999AEF2} = {CC07C89A-B410-4112-8686-A297FC0D34A8}
{FAA3150B-7230-4578-8CC0-775EDE947E7D} = {CC07C89A-B410-4112-8686-A297FC0D34A8}
{3F4AF8F0-63C2-4226-BA8C-3D9992EB59C5} = {3DE71730-143F-4835-A6B3-E501910EA94C}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8D31C3AE-36FF-4667-A2A7-0E670245A59E} SolutionGuid = {8D31C3AE-36FF-4667-A2A7-0E670245A59E}

@ -0,0 +1,57 @@
## How to use reflection to explore an assembly?
or
## How to use reflection to dynamically add a plugin to an application?
This sample is made of three projects. Be careful with the role and moreover, the links between each other.
#### 1) ex_036_001_Mammifère.csproj
This assembly contains a **_Mammifère_** class with a simple **_Name_** property and compiles to a dll in the **_ex_036_001_Reflection\bin_** directory.
#### 2) ex_036_001_ChatChienOiseau.csproj
This assembly contains three classes:
- 2 of them are inheriting from **_Mammifère_** (**_Chat_** and **_Chien_**),
- the other one is not inheriting from **_Mammifère_** (**_Oiseau_**).
Important: this assembly references the first one, and compiles to a dll into the **_ex_036_001_Reflection\plugin_** directory.
#### 3) Applications\ex_036_001_Reflection.csproj
This assembly compiles to an exe in the **_ex_036_001_Reflection\bin_** directory. It references the first assembly, but **_does not reference_** the second assembly.
- First, it parses the plugin folder and gets all files :
```` C#
DirectoryInfo folder = new DirectoryInfo(Directory.GetCurrentDirectory().ToString()+"..\\..\\..\\plugin\\");F
ileInfo[] files = folder.GetFiles();
````
- Next, it filters these files and launches an assembly analysis on .dll files only
```` C#
foreach (FileInfo file in files.Where(f => f.Extension.Equals(".dll")))
{
AnalyseDLL(file.FullName);
}
````
- In this **_AnalyseDLL(string filePath)_** method, first, it loads the assembly:
```` C#
Assembly a = Assembly.LoadFile(filePath);
````
- then, it gets all the exported types of this assembly (all public types):
```` C#
Type[] types = a.GetExportedTypes();
````
- for each type **_t_** in **_types_**, it then writes its name in the Console, and tests if it's a subclass of **_Animal.Mammifère_**
```` C#
Write(t.Name);
if(t.GetTypeInfo().IsSubclassOf(typeof(Animal.Mammifère)))
{
//
}
````
Remember that this Console App does not reference the assembly where the classes **_Chat_**, **_Chien_** and **_Oiseau_** are defined.
It only references the first assembly with the **_Animal.Mammifère_** class, so
this is the only class it knows at compile-time. It _discovers_ the others by reflection.
Now you can explore the types (if they are primitive, interfaces, abstract, delegate, generics ...) and their members (methods, properties...).
Have fun!
_Marc Chevaldonné, 27th of may 2019_

@ -0,0 +1,75 @@
// ========================================================================
//
// Copyright (C) 2013-2014 MARC CHEVALDONNE
// marc.chevaldonne.free.fr
//
// Module : Program.cs
// Author : Marc Chevaldonné
// Creation date : 2014-05-26
//
// ========================================================================
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using Animal;
using System.Linq;
using static System.Console;
namespace Reflection
{
class Program
{
static void Main(string[] args)
{
//permet d'accéder au dossier courant (ici l'endroit où se trouve l'exécutable)
WriteLine(System.IO.Directory.GetCurrentDirectory());
DirectoryInfo folder = new DirectoryInfo(Directory.GetCurrentDirectory().ToString()+"..\\..\\..\\plugin\\");
FileInfo[] files = folder.GetFiles();
foreach (FileInfo file in files.Where(f => f.Extension.Equals(".dll")))
{
AnalyseDLL(file.FullName);
}
}
static void AnalyseDLL(string filePath)
{
//chargement d'une dll dans ce dossier courant
Assembly a = Assembly.LoadFile(filePath);
//on récupère tous les types contenus dans cette dll dans un tableau "types"
Type[] types = a.GetExportedTypes();
//pour chacun de ces types :
foreach (Type t in types)
{
//on écrit le nom du type (nom d'une classe par exemple)
Write(t.Name);
//teste si le type dérive de Mammifère ou non
if(t.GetTypeInfo().IsSubclassOf(typeof(Animal.Mammifère)))
{
//si le type dérive de Mammifère, on écrit le nom du type Mammifère entre parenthèses
Write(" (" + t.GetTypeInfo().BaseType.Name + ")\n");
//on appelle le constructeur du type (chat ou chien par exemple) et on le référence à l'aide d'une
//référence sur un Mammifère (chat et chien dérivent de mammifère)
Mammifère bitxo = Activator.CreateInstance(t) as Mammifère;
//on affiche à l'écran le membre mName du type concerné (minou pour chat, toutou pour chien)
WriteLine(" je m'appelle : " + bitxo.Name);
}
else
{
//si le type ne dérive pas de Mammifère, alors on le dit
WriteLine(" ne dérive pas de Animal.Mammifère");
}
WriteLine();
}
}
}
}

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- ======================================================================
Copyright (C) 2013-2014 MARC CHEVALDONNE
marc.chevaldonne.free.fr
Module : ex_036_001_Reflection.csproj
Author : Marc Chevaldonné
Creation date : 2014-05-26
======================================================================== -->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<AssemblyName>ex_036_001_Reflection</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>ex_036_001_Reflection</PackageId>
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
<PackageTargetFallback>$(PackageTargetFallback);dnxcore50</PackageTargetFallback>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<ApplicationIcon />
<StartupObject />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>../../bin</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<OutputPath>../../bin</OutputPath>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MammifereDll\ex_036_001_Mammifere.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,25 @@
// ========================================================================
//
// Copyright (C) 2013-2014 MARC CHEVALDONNE
// marc.chevaldonne.free.fr
//
// Module : Chat.cs
// Author : Marc Chevaldonné
// Creation date : 2014-05-26
//
// ========================================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace Animal
{
public class Chat : Mammifère
{
public Chat()
{
Name = "minou";
}
}
}

@ -0,0 +1,25 @@
// ========================================================================
//
// Copyright (C) 2013-2014 MARC CHEVALDONNE
// marc.chevaldonne.free.fr
//
// Module : Chien.cs
// Author : Marc Chevaldonné
// Creation date : 2014-05-26
//
// ========================================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace Animal
{
public class Chien : Mammifère
{
public Chien()
{
Name = "toutou";
}
}
}

@ -0,0 +1,31 @@
// ========================================================================
//
// Copyright (C) 2013-2014 MARC CHEVALDONNE
// marc.chevaldonne.free.fr
//
// Module : Oiseau.cs
// Author : Marc Chevaldonné
// Creation date : 2014-05-26
//
// ========================================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace Animal
{
public class Oiseau
{
public Oiseau()
{
Name = "cuicui";
}
public string Name
{
get;
protected set;
}
}
}

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- ======================================================================
Copyright (C) 2013-2014 MARC CHEVALDONNE
marc.chevaldonne.free.fr
Module : ex_036_001_ChatChienOiseau.csproj
Author : Marc Chevaldonné
Creation date : 2014-05-26
======================================================================== -->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<AssemblyName>ex_036_001_ChatChienOiseau</AssemblyName>
<OutputType>Library</OutputType>
<PackageId>ex_036_001_ChatChienOiseau</PackageId>
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
<PackageTargetFallback>$(PackageTargetFallback);dnxcore50</PackageTargetFallback>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<ApplicationIcon />
<StartupObject />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>../../plugin</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<OutputPath>../../plugin</OutputPath>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MammifereDll\ex_036_001_Mammifere.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,30 @@
// ========================================================================
//
// Copyright (C) 2013-2014 MARC CHEVALDONNE
// marc.chevaldonne.free.fr
//
// Module : Mammifere.cs
// Author : Marc Chevaldonné
// Creation date : 2014-05-26
//
// ========================================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace Animal
{
public class Mammifère
{
public Mammifère()
{
}
public string Name
{
get;
protected set;
}
}
}

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- ======================================================================
Copyright (C) 2013-2014 MARC CHEVALDONNE
marc.chevaldonne.free.fr
Module : ex_036_001_Mammifere.csproj
Author : Marc Chevaldonné
Creation date : 2014-05-26
======================================================================== -->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<AssemblyName>ex_036_001_Mammifere</AssemblyName>
<OutputType>Library</OutputType>
<PackageId>ex_036_001_Mammifere</PackageId>
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
<PackageTargetFallback>$(PackageTargetFallback);dnxcore50</PackageTargetFallback>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<ApplicationIcon />
<StartupObject />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>../../bin</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<OutputPath>../../bin</OutputPath>
</PropertyGroup>
</Project>
Loading…
Cancel
Save