Why can't I reference one project from another (but CAN use statics)? - visual-studio

This one is weird. I've got a MonoDevelop/MonoTouch project (call it MyApp) that references another project (call it MyUtils), which is a Portable Class Library (targeting .NET 4.0.3, if that is relevant).
In the MyApp project, I've added a reference to MyUtils. In Visual Studio, this works properly: I can refer to the classes in MyUtils without any problem.
But in MonoDevelop on the Mac, if I try to refer to MyUtils from MyApp, I can't. It simply doesn't see the project, and can't, for instance, write something like:
using MyUtils.MyNamespace
If I do, I get a 'type or namespace could not be found' error.
But here's the weird part: MyApp can use the static classes in MyUtils. If I refer to a public static class in MyUtils from MyApp, it works! What could possibly explain this?!

What explains this is that the MonoTouch implementation of PCLs is a bit of a kludge at present.
The proper work is underway, but in the meantime you need to use an interim release of MonoDevelop, and you need to be aware that things like Intellisense and syntax highlighting don't really work in MonoDevelop.
See:
MonoTouch: creating multiplatform apps using Portable Class Libraries
http://slodge.blogspot.co.uk/2013/02/the-future-is-portable.html
Update - the interim release is hidden in a comment on that question:
For those doing PCL stuff, I've posted a patched MonoDevelop 3.1.1 build with improved PCL support here: http://files.xamarin.com/~jeff/MonoDevelop-3.1.1.dmg - it's still not perfect, but it's better than the official builds so far (my patches will be in a future official release) – jstedfast Feb 8 at 14:57

Related

Maui class library can't compile Android (No Android nameapace)

I'm trying to create a Maui class library that has platform dependent sections.
In the class library's platform section for Android I've added code for Android, but when I compile it tells me that it can't find the Android namespace. I've check the Nuget packages against the main program that does compile Android and there the same. I've unloaded both the main project and the class library and check the project code against each other and there almost identical. The only difference that I can find between the main project that does compile Android is that the class library has an extra net6.0 dependency.
I've created a ".NET MAUI Class Library (Preview)" in VS 2022 Preview 3. Indeed, something is wrong - especially with Intellisense. I did not find a way to suppress certain Intellisense errors, but I did succeed in getting it to build.
NOTE: I confirmed that most of the issues do not interfere with Building the project. Indeed, its possible that the problem is ONLY with Intellisense; I didn't rigorously determine whether Build always worked.
1) OPTIONAL: In .csproj, REMOVE .net6.0; from start of <TargetFrameworks>. BUT DON'T remove, if you are making a library that doesn't contain platform-specific code.
EXPLANATION: This only affects Intellisense; can Build without doing this.
Normally this is wanted in a .net6 class library, but until VS Intellisense correctly handles Maui Class Libraries, with their platform-specific code, this tends to cause extra Intellisense complaints. If you do (4) for all platform-specific files, you can probably leave .net6.0; in, without extra Intellisense errors.
2) Above any source file, is a dropdown that says YourLibName (net6.0-xxx). When working on Android code, pick YourLibName (net6.0-android).
EXPLANATION: This only affects Intellisense; can Build without doing this.
3) In your code, use global::Android instead of Android.
EXPLANATION: Intellisense seems to be confused about the context it is in. global:: ensures that it is looking for a "top-level" namespace.
4) In a class library, Intellisense isn't recognizing platform folders - wrap all code in appropriate #if ANDROID, #if IOS, etc.
EXPLANATION: This only affects Intellisense; can Build without doing this.
This removes errors for a class that is defined differently in multiple platforms; e.g class PlatformClass1.
5) using Android;, using Android.App, etc - do work (in platform-specific folder) when "Build" - even if Intellisense complains.
I had the same problem -- I was determined not to believe #ToolmakerSteve's response but I'm afraid he's correct. Especially #4 of his post about wrapping all platform specific content with
#if ANDROID
#endif
Also add it to your interfaces that reference platform specific namespaces.
Here's a link to a Microsoft page regarding this:
invoke platform specific code

iOS project doesn't reference a static library from Binding project when in Release mode

I've got a static library, which was used to generate the wrapping code by Sharpie. The library was Built after that (including, generated *.dll) successfully.
AppDefinition.cs contains the namespace and the mappings, like this:
namespace TheNamespace
{
// #interface TheParameters : NSObject
[BaseType(typeof(NSObject))]
interface TheParameters
{
The library itself built in Release mode with LinkTarget.ArmV7 | LinkTarget.ArmV7s | LinkTarget.Arm64.
However, when referencing this binding project from my iOS project, it works only in Debug mode.
When I change it to Release, the namespace (and all the related clasees) not available. Also, when exploring the binding library reference in Object Browser, it doesn't display any elements: it's totally empty.
Just to point that: it gets available when changing it in the dropdown to Debug and disappears on Release, what's interesting, undependently on what actually project is selected in Current Project dropdown!
What might be the issue? Thanks!
I think the problem should come from when building static library .When generating static library , there is a build type of release/debug to select.
Above screenshot shows static library types after building , there are three types (Two is Debug and One is Release ). You can see that tt distinguishes between release and debug .
After some Googling I found the solution.
The issue happens because of Visual Studio bug, I guess. And also referred here. (And it's weird it's not mentioned in Xamarin docs on Microsoft website.
To resolve the issue the Binding Project(s) must not reside in the same solution with the main project. Just remove them and attach the library as regular reference.

Recommended Cross-Platform (Windows and Android) Project Set Up using OpenTK

I am starting to develop a scientific software that I hope I will be able to run on multiple platforms. My plan is to use OpenTK for the rendering of the scientific models and plots. As of the moment I have a prototype that runs on Windows using OpenTK 1.1 libraries from http://www.opentk.com/ (a simpler version just with OpenTK and a more complicated one with OpenTK + WindwosForms). I am trying to port that prototype to Android.
It seems that the syntax using by the Xamarin.Android OpenTK library is nearly identical to the one that I am currently using for Windows (with the only difference that OpenGL -> OpenGL ES and GameWindow -> AndroidGameView) so the porting shouldn't be an issue. However, I was hoping that I could avoid a copy-paste method and get a more permanent solution having a shared OpenTK code between the Windows and the Android version.
I have read trough the Xamarin documentation about the shared vs PCL methods for cross-platform development. However, I still struggle to figure out how to set-up a Visual Studio solution with an Android and Windows project and a shared code that will include OpenTK. Is that even possible and can someone give me an example of how to do it? I did explore an example I found for rendering a rotating cube using OpenTK for a shared Android/iOS project (http://developer.xamarin.com/content/TexturedCubeES30/) but in my case I need to use a different OpenTK library for the Windows and for the Android project.
I also found this Do the Android and iOS versions of OpenTK have the same API? discussion. It is very similar to what I would like to do but in my case I am trying to setup a project for Windows and Android (for now).
Can I use only one OpenTK library (which one?) that is being called from both the Android and the Windows project and what will be the right way to set-up both projects so they share the same OpenTK code. This is the first time I am dealing with writing a cross-platform code so I am a bit lost.
Edit: I was able to get a prototype running using Shared Xamarin project and compiler flags as proposed below. Code was indeed not very pretty at places but I got over 70% code re-usability between the two platforms so it was worth the effort. This is how I used the compiler flags in case someone is looking for the same thing (credit to SKall from the Xamarin forums):
#if __ANDROID__
using OpenTK.Graphics.ES11;
#else
using OpenTK.Graphics.OpenGL;
#endif
I used the #if syntax similarly where there were small differences between the syntax of the routines.
It does not seem like OpenTK has its logic inside of a PCL in the first place, so your plans on putting it there are going to get hard to achieve.
However, if you split out your code, such that most of it is contained in classes, which are not highly dependent on the underlying platform, you will be able to create a Class Library Project for each platform and link your files between the platform specific projects. Inside of the classes it contains you will use #if definitions to choose whether to use AndroidGameView or GameWindow and the same goes for other platform specific types. It will make the code ugly, but this is the alternative to PCL.
You could try to see how much of the OpenTK code compiles inside of a PCL and inject the platform specific stuff at runtime, but it will require considerably more work from you. However, it will make the code a lot more cleaner to look at.
To ease the file linking, you could make one of those Shared Projects and chuck in all of the logic in there.
Some more info about code sharing here: http://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/sharing_code_options/
Dependency injection: https://en.wikipedia.org/wiki/Dependency_injection

How can I build a targetting pack for Portable Class Libraries?

I'm building some code with these portable class libraries at present.
I'm looking to target full .Net, WinRT Metro, Windows Phone, ... and then MonoTouch and MonoDroid. My experiments today show this can work - http://slodge.blogspot.co.uk/2012/04/experiments-with-portable-class.html
However, I have hit a fairly significant problem - MonoTouch and MonoDroid currently support these libraries in that you can consume PCLs as binary assemblies, but they don't allow linking between project files
e.g. I can reference MyLib.dll from a MonoDroid project, but I can't reference MyLib.csproj.
This is a problem as it means automated (resharper) refactoring doesn't work - and I seem to rely on this for most of my work!
I've seen that Microsoft publish targetting packs that allow you to extend class libraries, but I've not worked out where these install to or what they modify.
Here's the current Microsoft list: http://msdn.microsoft.com/en-us/hh487282.aspx
Does anyone have any knowledge about what these packs contain or how someone might make their own pack? If they're not too overly complex, then I would like to have a go at producing one for MonoTouch and/or MonoDroid.
This has come up a few times recently, so I wrote a blog post that should do what you want:
http://jpobst.blogspot.com/2012/04/mono-for-android-portable-libraries-in.html
Please let me know if have any issues!

LinqBridge Breaks Razor Views: .NET Version-Based File Output Restriction

Our project uses several NuGet packages, a few of which reference LinqBridge, a library that re-implements LINQ to Objects for C# 2.0. The LinqBridge.dll file lives under /packages/PackageName/lib/20/LinqBridge.dll, so it clearly is supposed to only apply to .NET 2.0.
The problem is that, even though every project in the solution is configured to build to .NET 4.0, the LinqBridge.dll binary gets copied over to the final /bin directory and wreaks havoc in Razor views. If I perform .Select() on an IEnumerable, there is an ambiguous call between the built-in LINQ call and the re-implemented one that LinqBridge provides.
I clearly do not need the re-implemented version; if I simply delete LinqBridge.dll from the output /bin directory, everything works just fine. However, that is not an acceptable permanent solution.
Is there any way I can configure something to quit copying that file, which is for an old .NET version, into the /bin output?
Edit: I duct-taped together a solution by adding this to the "Post-build event command line:" commands under "Build Events" in my solution properties:
del $(SolutionDir)\bin\LinqBridge.dll
It's still far from ideal, but at least it lets my project run for now.
NuGet has support for different binaries for different .NET versions so I would suggest that the packages you are using are built badly.
I would contact the authors of the packages and see if they can fix them so that only the net11 or net20 versions include LinqBridge.
Supporting Multiple .NET Framework Versions and Profiles
Many libraries target a specific version of the .NET Framework. For example, you might have one version of your library that's specific to Silverlight, and another version of the same library that takes advantage of .NET Framework 4 features. You do not need to create separate packages for each of these versions. NuGet supports putting multiple versions of the same library in a single package keeping them in separate folders within the package.
(more...)
A useful approach we found was using the LinqBridge.Embedded Nuget package instead of the standard LinqBridge package. This embeds Linqbridge as a C# file within your project, and hence does not get copied over to the bin folder and loaded into the context of the Razor view.
This was useful to us because an assembly we reference still needs to be built in .Net 2.0, as it is also referenced by a 2.0 application. Hence that assembly uses LinqBridge.Embedded, and the LinqBridge assembly does not end up in our 4.0 servers' bin folders.

Resources