Skip to content

Commit e896ba5

Browse files
committed
introduce TypeSource
1 parent 90ea520 commit e896ba5

4 files changed

Lines changed: 162 additions & 169 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using Mono.Cecil;
2+
3+
namespace NetArchTest.Rules.Assemblies
4+
{
5+
public interface IType
6+
{
7+
TypeDefinition Definition { get; }
8+
}
9+
10+
11+
internal sealed class TypeImpl : IType
12+
{
13+
public TypeDefinition Definition { get; }
14+
15+
16+
public TypeImpl(TypeDefinition definition)
17+
{
18+
Definition = definition;
19+
}
20+
}
21+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using Mono.Cecil;
6+
using NetArchTest.Rules.Dependencies.DataStructures;
7+
using NetArchTest.Rules.Extensions;
8+
9+
namespace NetArchTest.Rules.Assemblies
10+
{
11+
internal sealed class TypeSource
12+
{
13+
private static readonly List<string> exclusionList = new List<string>{ "System", "Microsoft", "Mono.Cecil", "netstandard", "NetArchTest.Rules", "<Module>", "xunit", "<PrivateImplementationDetails>" };
14+
private static readonly NamespaceTree exclusionTree = new NamespaceTree(exclusionList);
15+
16+
17+
18+
public static IEnumerable<IType> FromAssemblies(IEnumerable<Assembly> assemblies, IEnumerable<string> searchDirectories = null)
19+
{
20+
foreach (var assembly in assemblies)
21+
{
22+
if (exclusionTree.GetAllMatchingNames(assembly.FullName).Any() || assembly.IsDynamic)
23+
{
24+
continue;
25+
}
26+
27+
foreach (var type in ReadTypes(assembly.Location))
28+
{
29+
yield return type;
30+
}
31+
}
32+
}
33+
public static IEnumerable<IType> FromFiles(IEnumerable<string> fileNames, IEnumerable<string> searchDirectories = null)
34+
{
35+
foreach (var fileName in fileNames)
36+
{
37+
foreach (var type in ReadTypes(fileName))
38+
{
39+
yield return type;
40+
}
41+
}
42+
}
43+
44+
private static IEnumerable<IType> ReadTypes(string assemblyLocation, IEnumerable<string> searchDirectories = null)
45+
{
46+
ReaderParameters readerParameters = null;
47+
48+
if (searchDirectories?.Any() == true)
49+
{
50+
var assemblyResolver = new DefaultAssemblyResolver();
51+
foreach (var searchDirectory in searchDirectories)
52+
{
53+
assemblyResolver.AddSearchDirectory(searchDirectory);
54+
}
55+
56+
readerParameters = new ReaderParameters { AssemblyResolver = assemblyResolver };
57+
}
58+
59+
var assemblyDefinition = ReadAssemblyDefinition(assemblyLocation, readerParameters);
60+
61+
if (assemblyDefinition != null)
62+
{
63+
if (exclusionTree.GetAllMatchingNames(assemblyDefinition.FullName).Any() == false)
64+
{
65+
foreach (var type in GetAllTypes(assemblyDefinition.Modules.SelectMany(t => t.Types)))
66+
{
67+
yield return type;
68+
}
69+
}
70+
}
71+
}
72+
private static AssemblyDefinition ReadAssemblyDefinition(string path, ReaderParameters readerParameters = null)
73+
{
74+
try
75+
{
76+
if (readerParameters == null)
77+
{
78+
return AssemblyDefinition.ReadAssembly(path);
79+
}
80+
else
81+
{
82+
return AssemblyDefinition.ReadAssembly(path, readerParameters);
83+
}
84+
}
85+
catch (BadImageFormatException)
86+
{
87+
return null;
88+
}
89+
}
90+
private static IEnumerable<IType> GetAllTypes(IEnumerable<TypeDefinition> types)
91+
{
92+
foreach (var type in types)
93+
{
94+
if (exclusionTree.GetAllMatchingNames(type.FullName).Any() || type.IsCompilerGenerated())
95+
{
96+
continue;
97+
}
98+
99+
yield return new TypeImpl(type);
100+
101+
if (type.NestedTypes?.Any() == true)
102+
{
103+
foreach (var nestedType in GetAllTypes(type.NestedTypes))
104+
{
105+
yield return nestedType;
106+
}
107+
}
108+
}
109+
}
110+
}
111+
}

src/NetArchTest.Rules/AssemblyInfo.cs

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

0 commit comments

Comments
 (0)