mirror of
https://github.com/sbrl/PolyFeed.git
synced 2024-11-21 06:22:59 +00:00
Add reflection helpers
Imported from the SVM ACW for Component-based Architectures
This commit is contained in:
parent
10ce462412
commit
72a9f401ba
2 changed files with 89 additions and 0 deletions
88
PolyFeed/Helpers/ReflectionHelpers.cs
Normal file
88
PolyFeed/Helpers/ReflectionHelpers.cs
Normal file
|
@ -0,0 +1,88 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
namespace PolyFeed.Helpers
|
||||
{
|
||||
internal static class ReflectionUtilities
|
||||
{
|
||||
public static bool Verbose = true;
|
||||
|
||||
public static IEnumerable<Assembly> IterateLoadedAssemblies()
|
||||
{
|
||||
return AppDomain.CurrentDomain.GetAssemblies();
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> IterateAllLoadedTypes()
|
||||
{
|
||||
return IterateLoadedAssemblies()
|
||||
.SelectMany((Assembly nextAssembly) => nextAssembly.GetTypes());
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> IterateLoadedTypes(Assembly targetAssembly)
|
||||
{
|
||||
return targetAssembly.GetTypes();
|
||||
}
|
||||
|
||||
public static void LoadAssembliesDirectory(string directory)
|
||||
{
|
||||
foreach (string nextDll in Directory.EnumerateFiles(directory, "*.dll"))
|
||||
{
|
||||
AssemblyName assemblyName = AssemblyName.GetAssemblyName(nextDll);
|
||||
|
||||
// Check that a strongname is actually present
|
||||
if (assemblyName.GetPublicKeyToken().Length < 8)
|
||||
continue;
|
||||
|
||||
// Verify the strongname is valid.
|
||||
/*try
|
||||
{
|
||||
bool isOk = false;
|
||||
NativeMethods.StrongNameSignatureVerificationEx(nextDll, 0xFF, ref isOk);
|
||||
if (!isOk)
|
||||
continue;
|
||||
}
|
||||
catch (DllNotFoundException error)
|
||||
{
|
||||
Console.Error.WriteLine($"Warning: Unable to verify the integrity of the StrongName for '{nextDll}' (DLL not found: {error.Message}).");
|
||||
}*/
|
||||
|
||||
try
|
||||
{
|
||||
Assembly.LoadFrom(nextDll);
|
||||
// FUTURE: Consider using Assembly.ReflectionOnlyLoadFrom in a separate AppDomain to figure out if there's anything useful in an assembly before loading it for reals
|
||||
}
|
||||
catch (BadImageFormatException error)
|
||||
{
|
||||
if (Verbose) Console.Error.WriteLine($"Error loading '{nextDll}': {error.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Searches the types present in the specified assembly to find a type that implements
|
||||
/// the specified interface.
|
||||
/// </summary>
|
||||
/// <param name="targetInterface">The target interface that returned types should implement.</param>
|
||||
/// <param name="assemblyToSearch">The assembly to search through for matching types.</param>
|
||||
public static IEnumerable<Type> IterateImplementingTypes(Type targetInterface, Assembly assemblyToSearch)
|
||||
{
|
||||
if (!targetInterface.IsInterface)
|
||||
throw new ArgumentException($"Error: The specified type {targetInterface} is not an " +
|
||||
"interface, so it can't be used to search for implementing types.");
|
||||
|
||||
// FUTURE: Add caching here? Reflection is slow
|
||||
foreach (Type nextType in IterateAllLoadedTypes())
|
||||
{
|
||||
// Make sure it implements the specified interface
|
||||
if (!targetInterface.IsAssignableFrom(nextType))
|
||||
continue;
|
||||
|
||||
yield return nextType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -151,6 +151,7 @@
|
|||
<Compile Include="SnakeCasePropertySelector.cs" />
|
||||
<Compile Include="Helpers\HtmlHelpers.cs" />
|
||||
<Compile Include="Helpers\UserAgentHelper.cs" />
|
||||
<Compile Include="Helpers\ReflectionHelpers.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
|
Loading…
Reference in a new issue