I know how to branch the code based on Mono (Type.GetType("Mono.Runtime") != null) but even when the Mono code path is taken, Mono is attempting to load assemblies that would be required by the non-Mono code path. This is not all that surprising, but how do I get around the problem? I have tried putting the call to the non-Mono assembly in a different class, but that didn't help.
views:
53answers:
4Don't add the reference in the command-line compiler options. If you are using a high level IDE tool then you might have to play with its project settings to effect the same thing. There are other files that come into play too like AssemblyInfo.cs and might contain instructions about assemblies that you are considering. Also the program might be using types from App.Config (Configuration file) or Web.Config (ASP.NET) / dynamic type loading.
The only option to do it directly is Reflection all the way, so far as I can see.
I'd suggest a more roundabout approach: refactor all your code that is dependent on Mono or .NET into separate assemblies, one for each platform - let's call them MA and NA. Make sure that the entire API surface of your classes there is covered by common interfaces, which should be in the 3rd assembly, IA. After that, your main application references IA for interfaces, and uses Reflection just once to load either MA or NA depending on whether it's running on Mono or .NET, and obtain the instance of "top-level factory class". Once there, it just uses normal calls via IA interfaces to instantiate all other objects via that factory and work with them.
Don't rely for your dependencies on the fact that your code is JITted and that only called code is JITted.
Best is always to assume, that whatever is referenced will be loaded and has to be available. You user might choose to use AOT, which is Mono's counterpart of NGEN. Or subtle differences in how newer runtime versions handle things like serialization, remoting, security, reflection, etc. can lead to your references being loaded even your code does not use anything directly. (But the serializer might have pulled all types, which then loaded other assemblies)
Use interfaces or classic inheritance, or maybe events or other means of indirection to load the .Net parts only when they are appropriate. And by hat I mean an assembly that you don't reference but load dynamically.
Expanding on Pavel's answer you can use a plugin framework to help with the conditionality of loading bits of code that are specific to a platform. You can use Mono.Addins or MS' own open sourced Managed Extensibility Framework known as MEF (http://www.codeplex.com/MEF)