Sometimes you have to split your code into different assemblies. For example when I created a custom Admin Page which inherits from WebAdminPageBase (Microsoft.SharePoint.ApplicationPages). The problem with Microsoft.SharePoint.ApplicationPages is that it’s not deployed to the GAC.
Putting a reference to this assembly from my assembly, also containing custom web parts and other controls which have to be registered as SafeControls in the web.config, will result in deployment troubles when you use a WSP file. The problem is when SharePoint is going to register the safecontrols it will reflect your assemby and won't be able to access the Microsoft.SharePoint.ApplicationPages assembly because it’s not available in the GAC.
The same problem can be found using the Content Deployment option.
So you split your code in 2 assemblies, for example
foo.bar.ApplicationPages. But when your custom application page is depending on an internal type declared in
foo.bar you are in trouble. When compiling you will get the following message:
"CS0122: 'foo.bar.x' is inaccessible due to its protection level"
Now you have only one choice: make x public. Or maybe not?
It’s also possible to make your assembly share it's internals with other assemblies. Add the following to you code (in foo.bar):
[assembly: InternalsVisibleTo("foo.bar.ApplicationPages, PublicKey=0a240a ... c2f34c7")]
But the public key is not your public key token. Thanks to Burt Harris’s comment at the InternalsVisibleToAttribute Class you can find your real public key using the following command:
sn.exe -Tp foo.bar.dll
Now compile your project and there you go!