A third option (after considering the previous answers where they suggested ILMerge and the GAC) would be to use your own mechanism to load the DLL dynamically.
This is by far the hackiest, but if you're looking at options, this could be a solution for your problem. However, I would really suggest you use ILMerge (my favorite) or GAC.
The idea is to use the C# reflection API to load the DLL:
Assembly myDLL = Assembly.LoadFile("C:\\mydlls\\mytest.dll");
Then you can use either
Assembly.GetTypes() to enumerate the collection of classes inside the assembly, or get one by name using
Further, you would create an object of that class by calling an activator on it
Activator.CreateInstance(type) for a parameterless constructor, or get a constructor with
Type.GetConstructors() and invoke them using reflection.
To make your solution nicer -- i.e. not depend on a DLL on the file system, you could place the 'common' DLL in an Assembly TBB in Tridion, then read its bytes and create an Assembly from bytes. This is pretty much what Tridion templating engine does behind the scene. This could get complex though...
TemplateBuildingBlock tbb = session.GetObject("tcm:1-2-2048") as TemplateBuildingBlock;
byte byteArray = tbb.BinaryContent.GetByteArray();
Assembly myDLL = Assembly.Load(byteArray);