diff --git a/src/MTConnect.NET-Common/AssemblyExtensions.cs b/src/MTConnect.NET-Common/AssemblyExtensions.cs new file mode 100644 index 00000000..d754c105 --- /dev/null +++ b/src/MTConnect.NET-Common/AssemblyExtensions.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace MTConnect +{ + public static class AssemblyExtensions + { + /// + /// Get the types within the assembly that match the predicate. + /// for example, to get all types within a namespace + /// typeof(SomeClassInAssemblyYouWant).Assembly.GetMatchingTypesInAssembly(item => "MyNamespace".Equals(item.Namespace)) + /// + /// The assembly to search + /// The predicate query to match against + /// The collection of types within the assembly that match the predicate + /// + /// Code taken from https://stackoverflow.com/questions/7889228/how-to-prevent-reflectiontypeloadexception-when-calling-assembly-gettypes + /// + public static IReadOnlyCollection GetMatchingTypesInAssembly( + this Assembly assembly, + Predicate predicate) + { + var types = new List(); + try + { + types = assembly.GetTypes().Where(i => predicate(i) && i.Assembly == assembly).ToList(); + } + catch (ReflectionTypeLoadException ex) + { + foreach (var theType in ex.Types) + { + try + { + if (theType != null && predicate(theType) && theType.Assembly == assembly) + types.Add(theType); + } + // This exception list is not exhaustive, modify to suit any reasons + // you find for failure to parse a single assembly + catch (BadImageFormatException) + { + // Type not in this assembly - reference to elsewhere ignored + } + } + } + return types; + } + } +} \ No newline at end of file diff --git a/src/MTConnect.NET-Common/Assets/Asset.cs b/src/MTConnect.NET-Common/Assets/Asset.cs index 716be082..47e8fb24 100644 --- a/src/MTConnect.NET-Common/Assets/Asset.cs +++ b/src/MTConnect.NET-Common/Assets/Asset.cs @@ -112,9 +112,11 @@ private static Dictionary GetAllTypes() var assemblies = Assemblies.Get(); if (!assemblies.IsNullOrEmpty()) { - var allTypes = assemblies.SelectMany(x => x.GetTypes()); + var types = assemblies + .SelectMany( + x => x.GetMatchingTypesInAssembly( + t => typeof(IAsset).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract)); - var types = allTypes.Where(x => typeof(IAsset).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract); if (!types.IsNullOrEmpty()) { var objs = new Dictionary(); diff --git a/src/MTConnect.NET-Common/Devices/Component.cs b/src/MTConnect.NET-Common/Devices/Component.cs index b4af7876..5ed5d917 100644 --- a/src/MTConnect.NET-Common/Devices/Component.cs +++ b/src/MTConnect.NET-Common/Devices/Component.cs @@ -350,9 +350,11 @@ private static Dictionary GetAllTypes() var assemblies = Assemblies.Get(); if (!assemblies.IsNullOrEmpty()) { - var allTypes = assemblies.SelectMany(x => x.GetTypes()); + var types = assemblies + .SelectMany( + x => x.GetMatchingTypesInAssembly( + t => typeof(Component).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract)); - var types = allTypes.Where(x => typeof(Component).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract); if (!types.IsNullOrEmpty()) { var objs = new Dictionary(); diff --git a/src/MTConnect.NET-Common/Devices/Composition.cs b/src/MTConnect.NET-Common/Devices/Composition.cs index b8988a98..6881a0e2 100644 --- a/src/MTConnect.NET-Common/Devices/Composition.cs +++ b/src/MTConnect.NET-Common/Devices/Composition.cs @@ -209,9 +209,11 @@ private static Dictionary GetAllTypes() var assemblies = Assemblies.Get(); if (!assemblies.IsNullOrEmpty()) { - var allTypes = assemblies.SelectMany(x => x.GetTypes()); + var types = assemblies + .SelectMany( + x => x.GetMatchingTypesInAssembly( + t => typeof(Composition).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract)); - var types = allTypes.Where(x => typeof(Composition).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract); if (!types.IsNullOrEmpty()) { var objs = new Dictionary(); diff --git a/src/MTConnect.NET-Common/Devices/DataItem.cs b/src/MTConnect.NET-Common/Devices/DataItem.cs index d1ac031d..63615fd9 100644 --- a/src/MTConnect.NET-Common/Devices/DataItem.cs +++ b/src/MTConnect.NET-Common/Devices/DataItem.cs @@ -388,9 +388,11 @@ private static Dictionary GetAllTypes() var assemblies = Assemblies.Get(); if (!assemblies.IsNullOrEmpty()) { - var allTypes = assemblies.SelectMany(x => x.GetTypes()); + var types = assemblies + .SelectMany( + x => x.GetMatchingTypesInAssembly( + t => typeof(DataItem).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract)); - var types = allTypes.Where(x => typeof(DataItem).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract); if (!types.IsNullOrEmpty()) { var objs = new Dictionary(); diff --git a/src/MTConnect.NET-Common/Formatters/ResponseDocumentFormatter.cs b/src/MTConnect.NET-Common/Formatters/ResponseDocumentFormatter.cs index 72e291e3..1855ff81 100644 --- a/src/MTConnect.NET-Common/Formatters/ResponseDocumentFormatter.cs +++ b/src/MTConnect.NET-Common/Formatters/ResponseDocumentFormatter.cs @@ -191,10 +191,12 @@ private static void AddFormatters() var assemblies = Assemblies.Get(); if (!assemblies.IsNullOrEmpty()) { - var allTypes = assemblies.SelectMany(x => x.GetTypes()); - // Get IResponseDocumentFormatter Types - var types = allTypes.Where(x => typeof(IResponseDocumentFormatter).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract); + var types = assemblies + .SelectMany( + x => x.GetMatchingTypesInAssembly( + t => typeof(IResponseDocumentFormatter).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract)); + if (!types.IsNullOrEmpty()) { foreach (var type in types) diff --git a/src/MTConnect.NET-Common/Observations/Observation.cs b/src/MTConnect.NET-Common/Observations/Observation.cs index 3104e4a5..c051c949 100644 --- a/src/MTConnect.NET-Common/Observations/Observation.cs +++ b/src/MTConnect.NET-Common/Observations/Observation.cs @@ -793,9 +793,11 @@ protected static Dictionary GetAllTypes() var assemblies = Assemblies.Get(); if (!assemblies.IsNullOrEmpty()) { - var allTypes = assemblies.SelectMany(x => x.GetTypes()); + var types = assemblies + .SelectMany( + x => x.GetMatchingTypesInAssembly( + t => typeof(IObservation).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract)); - var types = allTypes.Where(x => typeof(IObservation).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract); if (!types.IsNullOrEmpty()) { var objs = new Dictionary();