MarimerLLC / cslaforum

Discussion forum for CSLA .NET
https://cslanet.com
Other
31 stars 6 forks source link

Csla - PCL vs Xamarin.iOS10 #306

Open ajj7060 opened 7 years ago

ajj7060 commented 7 years ago

We're getting starting building our mobile application on Xamarin.Forms, hoping to share as much code as possible. To this end, we've converted our business library to a shared project and then added a .Net 4.6 project for the business code on our existing WinForms app (and web sites, and windows services). We then created a PCL profile111 project for the business code to use in our Xamarin apps. To this, we added Csla-Core which uses the PCL version of Csla (portable-net45+win8+wpa81).

Xamarin created the projects for iOS, Android, and WP8.1 (and W8.1 and UWP, but we're not supporting those). We're now adding code into the Shared project for the mobile apps, which use some types from the business PCL.

In Debug mode, everything is fine. If I switch to Ad-Hoc / iPhone for the build configuration, I get the error:

Failed to resolve "System.Reflection.PropertyInfo Csla.Reflection.TypeExtensions::GetProperty(System.Type,System.String,Csla.Reflection.BindingFlags)" reference from "Csla, Version=4.6.500.0, Culture=neutral, PublicKeyToken=93be5fdc093e4c30" MyMobile.iOS

Now, if I look at both DLLS for Csla (in portable-net45+win8+wpa81 and Xamarin.iOS), Csla.Reflection.TypeExtensions only has the extension method IsSerializable, while the PCL has a bunch more (including the missing one). So, I understand the issue is that the Xamarin.iOS library is in fact missing the method in question, but I'm not sure how to go about fixing it (without creating Business.iOS and Business.Android, introducing yet more projects to build and conditional compilation flags).

Any ideas?

rockfordlhotka commented 7 years ago

As you are probably aware, the PCL can't execute directly, because several methods aren't implemented or are implemented "incorrectly" on a per-platform basis. Its only purpose is to expose an API surface area against which you can develop in Visual Studio.

At runtime it is the per-platform assembly that is used, because that's what's actually deployed to the client device and loaded into the running process/AppDomain.

Different platforms (flavors of .NET) provide different pre-existing API sets. In the case of ISerializable, some platforms have it and some don't. On platforms that don't have it, Csla.dll contains a definition for it (and generally an implementation).

One challenge with this, is that the APIs implemented on the various flavors of .NET keep changing - Microsoft keeps adding new stuff, especially as they move toward netstandard 2.0 - which should (fingers crossed) provide a much more predictable API surface area for all of us to use.

So what you are hitting might be a bug in CSLA. Or it might be something that worked, and now doesn't because Microsoft changed something in the iOS Xamarin API (really in mono).

However, the first and easiest thing to understand and check is this: at runtime the specific Csla.dll that is used is the one referenced by your host app - the top level "exe" project for your platform. When you reference CSLA-Core from NuGet you should get:

ajj7060 commented 7 years ago

Thanks @rockfordlhotka. I checked, and the projects are referencing Csla-Core as you described; Android is using lib/MonoAndroid10, iOS is using lib/Xamarin.iOS10 and the PCL is using lib/portable-net45+win8+wpa81.

Looking at the code for Csla.Reflection.TypeExtensions, it appears for Android/iOS TypeExtensions is defined to only provide the IsSerializable extension method to Type. So something (of course its not telling me what) is looking for the GetProperty(System.Type,System.String,Csla.Reflection.BindingFlags) call which is defined in the PCL Profile111 version, but compiled out of the MonoDroid10 / Xamarin.iOS10 versions.

What's weird is that changing the build configuration in VS yields different results; iPhoneSimulator compiles fine, but changing it to iPhone (to actually build the IPA) causes the compile to fail.

ajj7060 commented 7 years ago

I was able to create a repo of the issue here: https://github.com/ajj7060/TypeExtensionsError

This will require a Mac with Xamarin Studio, and changing the build configuration to Ad-Hoc / iPhone (not iPhoneSimulator). I suspect there might be some project setting specific to build configuration which could get me past this, but I haven't been able to find it yet.