Skip to content

Commit e964f8c

Browse files
committed
refactor reading types from assemblies
1 parent 8fe125f commit e964f8c

File tree

9 files changed

+192
-144
lines changed

9 files changed

+192
-144
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using Mono.Cecil;
4+
5+
namespace NetArchTest.Assemblies
6+
{
7+
internal sealed class AssemblySpec
8+
{
9+
private AssemblyDefinition assemblyDefinition;
10+
private IReadOnlyList<TypeDefinition> typeDefinitions;
11+
12+
13+
public AssemblySpec(AssemblyDefinition assemblyDefinition, IEnumerable<TypeDefinition> typeDefinitions)
14+
{
15+
this.assemblyDefinition = assemblyDefinition;
16+
this.typeDefinitions = typeDefinitions.ToArray();
17+
}
18+
19+
20+
public IEnumerable<TypeSpec> GetTypes()
21+
{
22+
return typeDefinitions.Select(x => new TypeSpec(x));
23+
}
24+
}
25+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using Mono.Cecil;
6+
using Mono.Cecil.Cil;
7+
using NetArchTest.Dependencies.DataStructures;
8+
9+
namespace NetArchTest.Assemblies
10+
{
11+
internal static class DataLoader
12+
{
13+
private static readonly List<string> exclusionList = new List<string>
14+
{
15+
"System",
16+
"Microsoft",
17+
"netstandard",
18+
"NuGet",
19+
"Newtonsoft",
20+
"Xunit",
21+
"Internal.Microsoft",
22+
"Mono.Cecil",
23+
"NetArchTest.Assemblies",
24+
"NetArchTest.Dependencies",
25+
"NetArchTest.Functions",
26+
"NetArchTest.Policies",
27+
"NetArchTest.RuleEngine",
28+
"NetArchTest.Rules",
29+
"NetArchTest.Slices",
30+
};
31+
private static readonly NamespaceTree exclusionTree = new NamespaceTree(exclusionList);
32+
33+
34+
public static LoadedData LoadFromCurrentDomain()
35+
{
36+
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
37+
var selectedAssemblies = assemblies.Where(assembly => assembly.IsDynamic == false);
38+
39+
return LoadFromAssemblies(selectedAssemblies);
40+
}
41+
public static LoadedData LoadFromAssemblies(IEnumerable<Assembly> assemblies, IEnumerable<string> searchDirectories = null)
42+
{
43+
var files = assemblies.Select(x => x.Location);
44+
45+
return LoadFromFiles(files, searchDirectories);
46+
}
47+
public static LoadedData LoadFromFiles(IEnumerable<string> fileNames, IEnumerable<string> searchDirectories = null)
48+
{
49+
var assemblies = Load(fileNames, searchDirectories);
50+
51+
return new LoadedData(assemblies);
52+
}
53+
54+
55+
private static IEnumerable<AssemblySpec> Load(IEnumerable<string> fileNames, IEnumerable<string> searchDirectories = null)
56+
{
57+
var readerParameters = CreateReaderParameters(searchDirectories);
58+
59+
foreach (var fileName in fileNames)
60+
{
61+
var assemblyDefinition = ReadAssemblyDefinition(fileName, readerParameters);
62+
if (assemblyDefinition == null) continue;
63+
64+
if (exclusionTree.GetAllMatchingNames(assemblyDefinition.FullName).Any() == true) continue;
65+
66+
var typeDefinitions = ReadTypes(assemblyDefinition);
67+
68+
yield return new AssemblySpec(assemblyDefinition, typeDefinitions);
69+
}
70+
}
71+
private static ReaderParameters CreateReaderParameters(IEnumerable<string> searchDirectories, bool readSymbols = true)
72+
{
73+
DefaultAssemblyResolver assemblyResolver = null;
74+
if (searchDirectories?.Any() == true)
75+
{
76+
assemblyResolver = new DefaultAssemblyResolver();
77+
foreach (var searchDirectory in searchDirectories)
78+
{
79+
assemblyResolver.AddSearchDirectory(searchDirectory);
80+
}
81+
}
82+
83+
return new ReaderParameters { AssemblyResolver = assemblyResolver, ReadSymbols = readSymbols, SymbolReaderProvider = new DefaultSymbolReaderProvider(false) };
84+
}
85+
private static AssemblyDefinition ReadAssemblyDefinition(string path, ReaderParameters readerParameters = null)
86+
{
87+
try
88+
{
89+
return AssemblyDefinition.ReadAssembly(path, readerParameters);
90+
}
91+
catch (BadImageFormatException)
92+
{
93+
return null;
94+
}
95+
}
96+
97+
98+
private static IEnumerable<TypeDefinition> ReadTypes(AssemblyDefinition assemblyDefinition)
99+
{
100+
foreach (var module in assemblyDefinition.Modules)
101+
{
102+
foreach (var type in module.GetTypes())
103+
{
104+
if (type.FullName.Equals("<Module>")) continue;
105+
if (type.FullName.StartsWith("<>")) continue;
106+
if (type.FullName.StartsWith("<PrivateImplementationDetails>")) continue;
107+
108+
if (exclusionTree.GetAllMatchingNames(type.FullName).Any()) continue;
109+
if (type.IsCompilerGenerated()) continue;
110+
111+
yield return type;
112+
}
113+
}
114+
}
115+
}
116+
117+
118+
internal sealed class LoadedData
119+
{
120+
public IReadOnlyList<AssemblySpec> Assemblies { get; }
121+
122+
123+
public LoadedData(IEnumerable<AssemblySpec> assemblies)
124+
{
125+
Assemblies = assemblies.ToArray();
126+
}
127+
128+
129+
public IEnumerable<TypeSpec> GetTypes()
130+
{
131+
foreach (var assembly in Assemblies)
132+
{
133+
foreach (var type in assembly.GetTypes())
134+
{
135+
yield return type;
136+
}
137+
}
138+
}
139+
}
140+
}

sources/NetArchTest/Assemblies/TypeSource.cs

Lines changed: 0 additions & 111 deletions
This file was deleted.

sources/NetArchTest/Extensions/Mono.Cecil/TypeDefinitionExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.CodeDom.Compiler;
23
using System.Collections.Generic;
34
using System.Linq;
45
using System.Runtime.CompilerServices;
@@ -104,7 +105,7 @@ public static bool OnlyHasNonNullableMembers(this TypeDefinition typeDefinition)
104105

105106
public static bool IsCompilerGenerated(this TypeDefinition typeDefinition)
106107
{
107-
return typeDefinition.CustomAttributes.Any(x => x?.AttributeType?.FullName == typeof(CompilerGeneratedAttribute).FullName);
108+
return typeDefinition.CustomAttributes.Any(x => x?.AttributeType?.FullName == typeof(CompilerGeneratedAttribute).FullName || x?.AttributeType?.FullName == typeof(GeneratedCodeAttribute).FullName);
108109
}
109110

110111
/// <summary>

sources/NetArchTest/NetArchTest.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<Copyright>(c) NetArchTest.eNhancedEdition</Copyright>
1010
<PackageLicense>https://github.com/NeVeSpl/NetArchTest.eNhancedEdition/blob/master/LICENSE</PackageLicense>
1111
<PackageProjectUrl>https://github.com/NeVeSpl/NetArchTest.eNhancedEdition</PackageProjectUrl>
12-
<PackageIcon>icon.png</PackageIcon>
12+
<PackageIcon>Resources\icon.png</PackageIcon>
1313
<RepositoryUrl>https://github.com/NeVeSpl/NetArchTest.eNhancedEdition</RepositoryUrl>
1414
<PackageTags>test architecture dependencies archtest</PackageTags>
1515
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
@@ -21,7 +21,7 @@
2121
</PropertyGroup>
2222

2323
<ItemGroup>
24-
<None Include="..\..\README.md">
24+
<None Include="..\..\README.md" Link="Resources\README.md">
2525
<Pack>True</Pack>
2626
<PackagePath>\</PackagePath>
2727
</None>
@@ -32,7 +32,7 @@
3232
</ItemGroup>
3333

3434
<ItemGroup>
35-
<None Update="icon.png">
35+
<None Update="Resources\icon.png">
3636
<Pack>True</Pack>
3737
<PackagePath>\</PackagePath>
3838
</None>

sources/NetArchTest/RuleEngine/RuleContext.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ internal class RuleContext
1414
public ConditionContext ConditionContext { get; } = new ConditionContext();
1515

1616

17-
public RuleContext(IEnumerable<TypeDefinition> inpuTypes)
17+
public RuleContext(LoadedData loadedData)
1818
{
19-
lodedTypes = inpuTypes.Select(x => new TypeSpec(x)).ToArray();
19+
lodedTypes = loadedData.GetTypes().ToArray();
2020
}
2121

2222

0 commit comments

Comments
 (0)