views:

493

answers:

5

I am working on an application that loads plugins at startup from a subdirectory, and currently i am doing this by using reflection to iterate over the types of each assembly and to find public classes implementing the IPluginModule interface.

Since Reflection involves a performance hit, and i expect that there will be several plugins after a while, i wondered if it would be useful to define a custom attribute applied at the assembly level, that could be checked before iterating over the types (possibly about a dozen types in an assembly, including 1 implementor of IPluginModule).

The attribute, if present, could then provide a method to return the needed types or instances, and iterating over the types would then only be a fallback mechanism. Storing the type info in a configuration file is not an option.

Would this improve performance, or does it just not matter compared to the time to actually takes to load the assembly from storage? Also, would this usage be appropriate for an attribute at all?

A: 

I'd have thought that asking an assembly for all the classes that are tagged with an attribute would also use reflection. It would then come down to which is a faster look up in the metadata, interface implementation or attribute marking?

Colin Desmond
I think I read somewhere that looking through the metadata is faster. But really we are only talking about milliseconds, I'm sure.
dboarman
+7  A: 

You could also have the plugable types in a configuration, so you know the exact classes instead of looping through all classes. Would have to have some configuration utility for this option...but could possibly get a good increase in performance depending on the number of classes you are looping through.

CSharpAtl
+1 -- this is exactly how I do it. Register the plugins with the application in the configuration. I then use a custom section handler to actually load the plugins.
tvanfosson
I, too, only iterate through an assembly when it is first added. I extract the details I need for later (plus some user-friendly info). This data is serialized for later use (via Activator). The user also has the option for 'auto-instancing' plugins at start up.
dboarman
+1  A: 

I believe both of Microsoft's two .net plugin frameworks, the Managed AddIn Framework (MAF) and the Managed Extensibility Framework (MEF) can use either attributes or reflection to discover plugins. So Microsoft seems to feel attributes are appropriate.

I'm not sure what the performance differences are, though.

dthrasher
+5  A: 

I will answer your question with a question: Why are you worried about this?

You're worrying about a potential performance hit in a one time operation because there might be several plugins at a later date.

Unless your application startup time is excessively long to a user, I wouldn't waste time thinking about it - there are probably much better things that you can work on to improve your application.

17 of 26
I first tried the configuration suggestion, but then i found out that it makes almost no difference, as i had to use Activator/Assembly.CreateInstance anyway.Now i am using an custom assembly-level attribute to get the type names, and as you guessed, i already found other areas where i can improve startup time.
Botz3000
Yea with the configuration you would just miss the looping over and checking to see if a class implemented your interface...you would just know which ones did.
CSharpAtl
Loading and getting a list of all types of many assemblies can be a performance and memory problem. By getting all types, your are loading a lot of type infrastructure in memory that the CLR would usually lazy load. That's something to be taken into account.
Lluis Sanchez
+1  A: 

A good solution is to cache all information about plugins. The first time the application is started it does a full scan of the plugin dlls, and saves the list of types found in a file. The next time the application starts, it loads the information from the file, which will be much faster than scanning all the dlls again. The application can also store a timestamp of each dll, so if it detects a change in a dll it can re-scan it and update the cache.

That's basically the approach followed by the Mono.Addins framework.

Lluis Sanchez
Thanks, good idea.
Botz3000