I'm using reflection to scan all of the assemblies in a folder for types that implement a certain interface and derive from a certain base class. The code looks like this:
foreach (string file in Directory.GetFiles(folder, "*.dll"))
{
Assembly assembly = Assembly.LoadFile(file);
Type foundType = (from type in assembly.GetTypes()
where type.GetInterfaces().Contains(typeof(TInterface))
&& type.BaseType.Name.LeftOf('`') == baseClass.Name.LeftOf('`')
select type).FirstOrDefault();
if (foundType == default(Type)) { continue; }
// Register our type so we don't need to use reflection on subsequent requests.
DependencyContainer.Register(typeof(TInterface), foundType);
return CreateInstance<TInterface>(foundType);
}
During a code review, two concerns were brought up concerning this piece of code. First, we can't shortcut the loop once we find a matching type; we need to loop through every file and throw an exception if we find more than one matching type. That brings me to the real issue here...
The code reviewer wondered if there was a better way to load every file. For performance reasons, we're wondering if we can loop through files already loaded in the app domain, instead of calling Assembly.LoadFile(file)
for every file. We thought, why load every file if it's already loaded? Is this a valid concern? Is loading a file this way the same as how files get loaded into an app domain? What would be an efficient way to loop through every file so we're not wasting processing time?
Note: The documentation for Assembly.LoadFile() isn't quite helpful:
Loads the contents of an assembly file on the specified path.
I'm not sure if that equates to how files are loaded into an app domain, or if that's a different scenario altogether.