You need to use assembly redirection to tell the loader to load a newer (but still compatible) assembly for your application when it's binding assemblies. This is something that you do in app.config or web.config, depending on the application type. For example (taken from the link above):
<dependentAssembly> <assemblyIdentity name="someAssembly" publicKeyToken="32ab4ba45e0a69a1" culture="en-us" /> <bindingRedirect oldVersion="7.0.0.0" newVersion="8.0.0.0" /> </dependentAssembly>
oldVersion allows for a version range, so multiple older versions can be mapped to a single new version of an assembly. Also, multiple bindingRedirect entries may be present.
Edit:
If you want to dynamically load a type from an assembly, you cannot reference the type itself (that is, you cannot have something like Class1 obj = ...; (var obj = ... is the same) because this ties the type to the one seen by the compiler. Assembly redirection would work but if you don't know the right version, you cannot use it.
Another option is to define interfaces in your main application and then have the various types in various assemblies implement these interfaces. This way you can dynamically load a type and cast it to a known interface type. For this, you can use either dependency injection (like LightInject, etc.) or you can have a config file that lists what assemblies contain a particular implementation of an interface. At the end you'd do something like:
IInterface obj = (IInterface) Activator.CreateInstance ( "assemblyname", "typename" ).Unwrap ();
This assumes that assemblyname refers to a known assembly that can be loaded and that typename is in that assembly and it implements IInterface.
Using interfaces ensures that the only hardcoded type at compile time is the interface and you can load any implementation from any assembly, as long as those implementations implement the right interface. This makes it easy to swap out various components.
Using a DI library, much of this is done for you - the various libraries deal with discovering types implementing interfaces in assemblies and then they give you a new instance when you request one.
You can also look at this answer to a similar question for some extra information: https://stackoverflow.com/a/26809961/682404
CreateInstanceAndUnwrap()