When referencing a .Net Standard project within a Xamarin solution, does all the code from the project get compiled into the app - xamarin.forms

Apologies if this sounds like a silly question. I'm not very experienced with how things are linked/bundled/assembled under the hood.
Before I begin, I'd like to say that I've tried reading documentation (such as https://learn.microsoft.com/en-us/xamarin/cross-platform/app-fundamentals/code-sharing) to find the answer, but was unable to.
If I have a Xamarin.Forms solution and I reference a .Net Standard project:
Question 1: Does all the code from this project get compiled and included into the app such that it may be disassembled later, or is it only code from classes that I actually make use of that gets included?
Bit more elaboration:
For example, I may have a School class that expects an IStudent (inject via DI), and a Student class that implements IStudent. Both of these exist in the .Net Standard project that I reference in the Xamarin.Forms project. However, if I only actually make use of the Student class (by registering it with type IStudent in my IoC container), will the code from School get included in the built app as well?
Question 2: If all the code from the project does get included, is there a way to forcefully specify which classes to include/exclude by way of some configuration setting, attributes, 3rd-party library, or something else?

As far as i know everything in the NETStandard project get compiled and shipped with the app.
If you want to remove unused code from compiled assemblies you have to use the linker.
To link everything, you have to select "Sdk and User Assemblies".
The linker tries to dont strip away mthods and fields you are using, but often is too aggressive (for example, methods referenced only by reflection will be stripped).
Luckily there are few methods where you can fine-tune the linker behaviour and make it work. Some link to elaborate on:
Linker in iOS and Android
https://learn.microsoft.com/en-us/xamarin/ios/deploy-test/linker
https://learn.microsoft.com/en-us/xamarin/android/deploy-test/linker
Official doc about the linker config:
https://learn.microsoft.com/en-us/xamarin/cross-platform/deploy-test/linker
Useful blogposts:
https://xamarinhelp.com/xamarin-linker/
https://medium.com/#harrycblum/reduce-your-xamarin-app-size-with-linking-26247edc87f6

Related

How to use .NET 6-windows and .NET 6 targets in one library

I've segregated my WinUI 3 application into different layers: Application, Infrastructure, Presentation etc.
And all the projects have targets: net6.0-windows and I want to move it to the Uno Platform.
So, I've added a new target: net6.0
And at this moment the problem arises:
Type [WinUI] component already defines a member, called InitializeComponent or some problems with binding.
Is it possible to make such type of library with targets to net6-windows and net6.0?
For the Windows app project itself, you need to use net6-windows, as that provides additional dependencies specific to Windows app projects. All other libraries (non-app projects) can then use net6.0.
Regarding the specific error message, you are getting, the reason might be the generated files have some kind of conflict - you can try deleting the obj and bin folders and rebuild.
The easiest way to make existing Windows app support Uno would probably be to create a blank Uno solution and then migrate the code there (as the solution has already the required setup for platform-specific projects prepared and you can then just add your code.
Uno also provides templates for cross-targeted libraries, so you might be able to use similar approach. The one linked is for "UWP" solution however, so to make it WinUI, you would need to switch from uap10.0.18362 to net6-windows.

Difference between Newtonsoft Json DynamicValueProvider and ReflectionValueProvider?

I'm in the process of porting a Asp.Net Core Website targeting the full framework to a website that targets Asp.Net Core 3.
In that process I have hit a snag. The website references the Newtonsoft 11.0.3 NuGet package and among other things uses the Newtonsoft.Json.Serialization.DynamicValueProvider class.
Interestingly that class exists when targeting the full framework but does not exist when targeting netcoreapp3.1 and so Visual Studio is producing compilation errors stating that the class doesn't exist. At first that seemed crazy to me, but I checked the source code for the class and sure enough it contains the following conditional compilation statement wrapped around the whole class
#if HAVE_REFLECTION_EMIT
Apparently the netStandard 2.0 dll in the NuGet package that my netcoreapp3.1 project would use causes the conditional compilation statement to not include the DynamicValueProvider class.
So I did some poking around in the Newtonsoft.Json.Serialization namespace and I see that there is a ReflectionValueProvider class available that does not contain such conditional compilation and is available when targeting netcoreapp3.1
I've looked at the source code for both the DynamicValueProvider class and the ReflectionValueProvider class and I'm unclear on the difference. Both appear to get or set the value of a property or member type based on the MemberInfo passed in into the constructor. Both appear to use reflection to accomplish their work. As I mentioned, apparently DynamicValueProvider needs reflection Emit ability and ReflectionValueProvider does not. Emit ability apparently is used to Emit IL as best I can tell.
So I wonder if perhaps the two are drop in replacements for each other except that maybe DynamicValueProvider might be faster since it apparently leverages IL Emitting. But that's just a hunch. I'd prefer to have a more concrete understanding of the differences between the two classes before I start swapping the one for the other in this existing codebase as a way to get to .Net Core 3.
Can you provide me with better insight into the differences between the DynamicValueProvider
class and the ReflectionValueProvider class, or at least confirm my hunch?
We had updated Newtonsoft.Json from 9.* to 12.0.3 version, and observed performance degradation on paths that includes json serialization. All paths lead to DynamicValueProvider. Fortunately, we had global descendant for DefaultContractResolver, and I was able to overload CreateMemberValueProvider method to return ReflectionValueProvider.
For now we are continue testing the new version, but I can say that from performance perspective ReflectionValueProvider works faster than DynamicValueProvider.
I think there is a correlation with the fact that NetStandard 2.0 is also used to build Xamarin.Forms applications for iOS which require an AOT compilation.
As written here:
Limitations of Xamarin.iOS
"Since applications using Xamarin.iOS are compiled to static code, it is not possible to use any facilities that require code generation at runtime."
and
"No Dynamic Code Generation.
The System.Reflection.Emit is not available"
For example, this is a System.Text.Json limitation that actually cannot be used in Xamarin.Forms projects for iOS. More info here.
System.Text.Json Serializer does not appear to work on Xamarin iOS

MvvmCross MvxApplication class overriding for different platforms. (Plus, encryption)

I've got two questions here. The first one is just specific and another one is more general, but is a source of the first one.
So, my specific problem: I want to use Encryption (actually, Hashing) algorithms with using System.Security.Cryptography namespace (for instance, SHA256Managed class).
I found out that (happily) Xamarin has implemented those in System.dll.
But it is not portable and obviously can not be used from Core application directly.
But I've also found another great project -- PclContrib -- which allows you to do that. But, unfortunately, they don't have the implementation for Touch and Android. (However, that still works great for Desktop (Web) and Windows Phone, plus, still can be included into Core (as it uses portable project)).
Anyway, to solve that nicely, I've decided to create some base class for the encryption methods and then override core methods which require the custom dll (for any custom system).
The way I did it (at least, trying to do) was:
Defining virtual method in Core App base class:
public virtual IEncryptionProvider CreateEncryptionProvider()
Overriding Core App class in Touch project with overriding CreateEncryptionProvider (which creates an instance of TouchEncryptionProvider class instance).
Core:
public class App : MvxApplication
Touch:
public class AppTouch : App
Launching it in Touch setup.cs:
protected override Cirrious.MvvmCross.ViewModels.IMvxApplication CreateApp (
{
return new AppTouch();
}
But, that does not work for me. On startup I've got this exception message in log:
"Exception masked KeyNotFoundException: Could not find view for Mynamespace.Etc.LoginViewModel", which works fine when I do new App() instead. I am not sure if that message shows actual problem (as before it was saying the same even that was a problem with some third-party dll, unrelated to views at all). But speaking shortly, that's just a primitive inheritance of App : MvxApplication, but placed not in Core but Touch project.
So, does it requeire some more custom initialization for such situations or do I miss something else?
And, actually, more general question is how should I build such Multiplatform approaches? Actually, now I've got similar problem with HttpUtility.UrlEncode, which I would want to use in my Core project.
What is the MvvmCross "philosophy" to handle such situations?
Thank you.
For the 'viewmodel not found' problem, this is caused because mvvmcross by default only looks for viewmodels in the Assembly containing your app.
If you want it to look in other assemblies, override ViewModelAssemblies in Setup.cs - see how this done in, for example, MvvmCross - structuring shared View Models and Views
For general multplatform approach, please read questions and answers like:
Platform-specific IoC in MVVMCross
Instantiation of ViewModels and Service classes
Please also remember you don't have to use PCLs - if you prefer to use file-linking between multiple platform-specific core projects, then you can of course use this approach.
Finally, please also try to ask one question per question - I find it makes stackoverflow work better for users and with search engines too. If you need to link questions, then you can just add a hyperlink reference - stackoverflow then marks them as related.

Prism and Using Unity IoC in Prism

I am a total newbie on Prism. I have been getting to understand a lot from questions on SO and from various Blogs. I am using latest build – V2
I want some explanations on things that may be pretty easy things for you guys but it’s just not getting into my brains (small one for that).
Instead of doing it all right the first time , for which I have spent more than two weeks looking at various blogs, webcast …., I thought to start a project and learn. The amount of information on those hundreds of sites was overwhelming and difficult to digest.
Currently my project is setup like this
Shell --  Menu Module- ViewModel - - -> Menu Service -- -- > Menu Repository --- Data
All are in different assembly
MyShell --- MenuModule ---MyServices -- Myrepository
Shell is required to reference modules ( thought I am sure I can add it using string) later on .
ViewModel has a reference to View - Can live with it for now
View Model requires to use menu service and menu service uses repository
All are built with constructor injection. I have it working now by having module reference MyService and Myrepository projects and then registering types at module level.
But this does not feel good. I don’t want to hard reference any projects. If we are referencing projects why use IoC. In MenuModule.cs ( which is in the root of module) I can register views with unity container
I think I am getting a feel that the answer to this one may lie in the first question
Is Configuration file the answer/
Should I use configuration file for
true decoupling?
If (somehow) we can
register types from code, should we
register types at module level ( I
don’t want to have hard reference to projects)
I need to know the
Interfaces in advance so do you
recommend separate assembly for just
Interfaces?
Bear with me if the questions sound real stupid 
You don't need a configuration file for true decoupling. All you need is to register your types in your shell's bootstrapper. I usually break up my projects and refs like this.
Contract Assembly
(Contains only a few simple types and interfaces)
Referenced by:
Shell
Modules
Shell
(Contains concrete implementations of interfaces defined in Contract assembly)
Referenced by:
No one
Modules
(Declares dependencies on interfaces defined in Contracts assembly, for instance IMenuRegistry)
Referenced by:
No one (I use a Directory Module to search for modules in a directory)
Here's a sample project I put together. In this sample I reference the module from the shell for simplicity's sake, but you can remove that reference and use a directory module catalog to load the compiled module at runtime:
http://dl.getdropbox.com/u/376992/CAGMenus.zip
Hope this helps,
Anderson
You're definitely on the right track. Use the configuration file to register your types, and put the interfaces in a separate assembly.

Can Microsoft Code Contracts be used with an ASP.NET Website?

I'm currently using Microsoft Code Contracts in an ASP.NET MVC application without any issues but I can not seem to get it quite running in a basic ASP.NET Web site. I'm not entirely sure it was made to work with this type of project (although it shouldn't matter) so I wanted to bring it up to everyone.
I can compile the contracts just fine but the code skips over them since I'm assuming it hasn't been enabled through the Properties Page like you would do in other project types (ie ASP.NET MVC). I've gone to the property page of the project (which displays a dialog instead of the typical properties page) in my ASP.NET web site but it does not yield the same menu options and as such, doesn't have a section devoted to Code Contracts.
Also, I have Microsoft Code Contracts properly enabled within a class library project that I use to separate my business logic from the web site. The contracts compile fine but when a contract is violated, it throws a rather uninformative "Exception of type 'System.ExecutionEngineException' was thrown" error with no inner exception. My contract specifies a message to display upon violation but it is nowhere within the exception. It simply halts the execution of the process (which I believe is the default functionality for Microsoft Code Contracts).
I can't find anywhere that explicitly states that a particular project type can or can't (or shouldn't) be used with Contracts so I just wanted to see if anyone has had this issue.
Thanks for any help!
I had the same problem and this is how I solved it:
In the Referenced Class Libraries, right click -> properties -> code contracts.
Make sure "perform contract checking" is checked. I had mine set to "Full"
Contract Reference Assembly: make sure it is set to "Build"
Save your changes.
In the Referenced Class Libraries that have no contracts in their code, set the Contract Reference Assembly to "Do Not Build".
Then in the MVC project, have the Code Contracts "perform contract checking" checked. I had mine set to "Full".
Hope that helps somebody.
This sounds less like a Contracts and more like a build/config issue. Have you tried to deploy a prebuilt website? Are you sure that your website code sees the contracts code? Is the ASP.NET runtime using the CLR 4.0, or does it see the earlier Microsoft.Contracts.dll? Etc.

Resources