The common mistake in using reflection is extracting some types and type members by names. This is not supportable, because those names become "magic words": any refactorization can lead to change of these names; and the mismatch between names declared in code and in data cannot be detected as a compilation error.
At the same time, right approach is 100% reliable and will withstand any renaming. Here is what you can do:
Define some plug-in interface. It can be defined in some assembly referenced by both host application and plug-in assemblies. A bit more tricky way is to define it right in the host application assembly. It always can be done, because application assembly can be referenced by a plug-in assembly exactly as it was a library; it would not create any circular dependencies, because the application assembly does not depend on plug-ins, only the runtime depends on them.
Now, when you load the plug-in assembly, the host application can scan its types and determine the one(s) implementing the plug-in interface(s). This can be done using this function:
http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom%28v=vs.110%29.aspx[
^].
I do even better. I define a special assembly-level attribute (
System.AttributeTargets.Assembly
; please see
http://msdn.microsoft.com/en-us/library/system.attributeusageattribute%28v=vs.110%29.aspx[
^],
http://msdn.microsoft.com/en-us/library/system.attributetargets%28v=vs.110%29.aspx[
^]) used just to claim which type(s) should be checked as implementing the plug-in interfaces. Then the search in the list of all assembly types is excluded.
The bigger problems appear when the set of loaded plug-ins should vary during runtine, that is, when you need to unload some assemblies. For important reliability reasons, .NET does not allow that. So, you would need to load plug-ins in separate Application Domains which can be fully unloaded, but it requires working with IPC, to reach through the boundaries between Application Domains. You can find the detail in my past answers:
Gathering types from assemblies by it's string representation[
^],
C# Reflection InvokeMember on existing instance[
^],
Projects and DLL's: How to keep them managable?[
^],
Dynamically Load User Controls[
^],
code generating using CodeDom[
^],
AppDomain refuses to load an assembly[
^],
Create WPF Application that uses Reloadable Plugins...[
^].
—SA