MvvmCross file plugin still required? - c#

Regarding the file plugin (OS independent file system access) for MvvmCross:
Do I understand correctly that this plugin was created at a time when file system access wasn't yet possible using .NET standard?
Meaning for new projects there's no reason to use the file plugin and I can use .NET standard without any drawbacks?

The MvvmCross.Plugins.File plugin was created back when we had Portable class libraries and didn't have any profile that had any System.File.IO namespaces available to us.
So with the introduction with .NET Standard, most of what it does has become obsolete. So you are right to say that for new projects, you could get away without having to use this plugin at all, because all of the API is available to you in .NET Standard.

Do I understand correctly that this plugin was created at a time when file system access wasn't yet possible using .NET standard?
No, MvvmCross is a cross-platform MVVM framework.
Among the features MvvmCross provides are:
ViewModel to View bindings using own customizable binding engine,
which allows you to create own binding definitions for own custom
views
ViewModel to ViewModel navigation, helps you share behavior on
how and when to navigate
Inversion of Control through Dependency
Injection and Property Injection
Plugin framework, which lets you
plug-in cool stuff like GPS Location, Localization, Sensors, Binding
Extensions and a huge selection of 3rd party community plug-ins
For more details, you could refer to the link. https://github.com/MvvmCross/MvvmCross-Samples
Meaning for new projects there's no reason to use the file plugin and I can use .NET standard without any drawbacks?
Plugins have advantages for framework, but implementing direct in the UI projects is perfectly acceptable too.

Related

How to reference class from iOS project to the main project in xamarin

I'm creating an app in which, the login will be handled using auth0. But due to the available Auth0 NuGet packages, I had to create separate login pages for android and iOS. So in the app.xaml.cs class, I now have to reference Login_iOS for case Device.iOS: MainPage = new Login_iOSā©(); but I am met with an error, as xamarin cannot find the class Login_iOS. I'm pretty sure that this is because I haven't referenced it correctly, and I can't seem to find a way to reference it correctly. The screenshots below should help me explain my situation.
Using an IoC (Inversion of Control) is one way to go as pointed out by Shawn, but understand that IoC is a name for one method of calling into platform specific code from a platform agnostic library project like a .NET Standard project. You have to decide on what IoC library to use, or whether to use IoC functionality that is built into some cross-platform frameworks like MvvmCross or even Xamarin.Forms Dependency Service (which is not a true IoC container but more of a service locator, but it does work to allow you to call platform specific code from a .NET Standard or PCL library project, which is ultimately what you want to do).
That said, there is another option for your core Xamarin.Forms code and that is to use a Shared Library project type. .NET Standard is by far the more common and the option that is suggested when you follow the getting started docs for Xamarin.Forms (and Xamarin.Forms != Xamarin see (1) below) You can select this when you create your Xamarin.Forms solution:
With a Shared library project type for your core Xamarin.Forms code, you will have access to everything that is referenced in your platform specific projects so you will access to everything that you have access to in the Xamarin.iOS and Xamarin.Android projects directly. No IoC or Dependency services are necessary.
There has always been much debate on whether using a Shared Library project or a .NET Standard project is the best way to go. There are pros and cons to each. In a nutshell using a .NET Standard project forces you to use IoC to call platform specific code from the library project, and use custom renderers to access platform specific properties of UI controls, whereas a Shared Library project give you full access to all the classes and libraries that are available to the platform specific project, making Dependency Injection unnecessary... BUT when using a Shared project, since you can have both Xamarin.Android specific and Xamarin.iOS specific code in the same Shared project, you need to use compiler directives (#if and #endif) so that iOS specific code is only compiled when building the iOS project and Android specific code is only compiled when compiling the Android project. Not doing so can cause compile and/or runtime issues. Here is a simple piece of code to show you how to use the compiler directives to isolate iOS and Android specific code. This simple sample will create a button that when tapped will present an Alert. How to present an Alert is different between iOS and Android so we need to isolate those bits of code in the button click event handler so the correct code runs on the correct platform.
First define the compiler symbols in the Project Options. Right click on the Android project and select Project Options and select Compiler on the left. Then in the Define Symbols field, add ANDROID;, e.g.:
Then do the same for the iOS project (but entering IOS obviously):
It is worth noting that this is a configuration dependent setting, so you need to add these symbols for all of the configurations that you will use to build your projects.
Next create the button in MainPage.xaml:
<Button Text="Show me an alert!"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Clicked="Handle_Clicked" />
Then in the MainPage.xaml.cs code behind file:
void Handle_Clicked(object sender, System.EventArgs e)
{
#if ANDROID
Toast.MakeText(MainActivity.Context, "I'm an Android Toast!", ToastLength.Long).Show();
#endif
#if IOS
var alert = new UIAlertView("I'm an iOS Alert!", "I'm deprecated. but using here because I do not have easy access to my view controller at this time", null, "OK", null);
alert.Show();
#endif
}
You will also need the compiler directives around the using statements:
#if ANDROID
using Android.Widget;
using SharedSample.Droid;
#endif
#if IOS
using UIKit;
#endif
So hopefully now you better understand how to make cross platform apps and some of the challenges around sharing code and using platform specific code. All that said, you still will not be able to add a native iOS page (or native Android page) to your Xamarin.Forms MainPage property since the iOS page is NOT a Xamarin.Form page (MainPage can only accept a subclass of a Xamarin.Forms Page), but this should show you how to call platform specific code from your shared code.
Oh, now I see in your screenshots that you added your Xamarin.Forms XAML page to the iOS project???? No, that is not the way around your issue. I would seriously suggest you sign up for Xamarin University. You need more than just code snippets, you need to better understand cross-platform development and my not-so-brief primer here is not nearly enough to get you going from what I can see.
BUt you know what, I think there is a OAuth library for Xamarin Forms, so maybe you can make that work as it should do all the platform specific stuff for you.
Nuget page: https://www.nuget.org/packages/Xamarin.Auth/
Github page: https://github.com/xamarin/Xamarin.Auth
Docs: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/authentication/oauth
Good luck!
(1) Xamarin was a company that was purchased by Microsoft. Xamarin made SDKs that allowed making apps for iOS, Mac, and Android using C# and the .NET framework. Xamarin.iOS SDK is used for making iOS apps, Xamarin.Mac for Mac apps, and Xamarin.Android for Android apps. All use Mono which is an open source port of .NET (since .NET only ran on Windows and other Microsoft platforms at the time... though there is now .NET Core that is cross-platform... but that is another topic).
Later Xamarin introduced Xamarin.Forms which is a cross-platform UI (User Interface) library that allows creating the UI in common code and/or XAML. Prior to Xamarin.Forms, the UI for each platform had to be created in the platform specific projects, i.e. the UI for iOS would be in Xamarin.iOS project, UI for Android would be in Xamarin.Android project, etc., but all could call into back end code (i.e. web requests, models, etc.) that resides in one shared library project, allowing about 80% of the total code to be shared between the different platform app projects. With Xamarin.Forms, for a simple app, 100% code sharing is possible. Xamarin.Forms does still use Xamarin.iOS and Xamarin.Android projects, as well as UWP projects on Windows, to kick off the UI, but Xamarin.Forms uses renderers to render the Xamarin.Forms UI Controls into platform specific controls, i.e. a Button in Xam.Forms renders to a UIButton on iOS and an Android Button on Android. However Xamarin.Forms only gives you access to core common properties of the native controls, so if you need to access specific native properties or features, you have to use a custom renderer (to modify UI controls on the native platform and have access to native control's properties) and/or dependency service (to run platform specific code from the core Xam.Forms library project).
Your base project cannot reference the platform specific project. If you could do that, you would be back in the boat of using platform specific libraries on the wrong platform.
Instead, you need to create a class or interface in your base project that each of your platform specific projects can extend. This way, you can pass that base class between projects without needing to know about any of the platform specific libraries that are being used.
I would recommend an IoC (Inversion of Control) pattern for this situation. It abstracts the reference handling for you and simplifies the registration of your various services. Take a look at this article which is solving the exact same type of situation.
I hope this helps!

Is there any way to share code between UWP apps and WPF apps?

To be clear, I follow the MVVM pattern, and I want to structure my project such that I can share my model code between a UWP app and a standard WPF app. The code I want to share has no UI. I don't relish the thought of finding new tools to replace the ones that I've been using for years that take care of certain tasks like logging, connecting to a document oriented database, etc.
I attempted to start writing a UWP wrapper around some code I already have and reference the model project directly. Visual Studio refused to let that happen, showing me an error message that says "Unable to add a reference to project 'ACK.Model'". The same thing happened when I attempted to put the model in a Universal Library and reference it from a WPF app. I'm not trying to share WPF code. Just the model layer that has no reference to UI libraries.
This is a scary proposition, because it means that if I want to do anything substantial I have to choose to either jump 100% to UWP or stay 100% WPF. NewtonSoft.JSON might have a universal distribution (ASP.NET MVC), but what about ElasticSearch.NET, and other tools needed to make important apps?
I found where the "Portable Class Library" project type was hiding. PCLs will allow me to share my code across WPF and Universal apps as that was one of the options. This solves the simple case of the Model part of my code, but I (still) can't use some of the libraries I want. There are still a large number of libraries that I need that do not have PCL available.
About a year later, with the advent of Visual Studio 2017 there is a more complete solution. If you target your libraries to .Net Standard then the library is compatible with both .Net Core apps and the monolithic .Net targeted app. The support for standard .Net libraries and APIs is fairly complete, as is the support for modern C# language features.
The general advice now is this:
Target .Net Standard for all libraries
Target the appropriate platform for your actual application. (UWP or WPF).
NOTE: if your library has to interact with C libraries or applications, you have to take extra care to make sure you load the correct version.
It appears that there is a solution, but it has to be adopted by the whole tool chain you want to use. When Microsoft introduced Windows Store apps in Windows 8, they also introduced a Portable Class Library (PCL). The purpose of the PCL is to share code between different parts of your application.
When you create a PCL in Visual Studio 2015, you can specify the types of APIs you want it to be accessible from:
Universal Apps
Mono
.Net Core 5
.Net 4.6
This of course, limits the APIs available to you but most of the ones you want to use are OK as long as it's not UI related. There are other limitations as well:
Your project can only be edited in Visual Studio 2015 or greater
You don't have access to special directories from the Environment variable (i.e. user Documents directory, etc.)
You can't link to a library designed for only one of your target platforms (i.e. libgit2sharp, etc.)
There's no way to browse the API for this subset--MSDN needs to get on the stick. MSDN has updated much of the API documentation, but it's still difficult to figure out what applies to your PCL
However, you can link any library designed for a single target platform to your PCL. It's not ideal, but it's better than nothing.
The ASP.NET MVC stack has been ported to using PCLs, so you can use NewtonSoft.JSON directly as well as any other of those libraries used by that application. However, there are several libraries that have not been ported.
This arrangement forces you to think about how you want to integrate better. The .Net Core 5 seems to be stable, but support is in it's infancy. The current generation of Universal Apps as of VS 2015 update 1 uses .Net Core 5 directly.
There are several features from Nuget that are not currently supported even though work is under way:
MS Build extensions (major changes to MSBuild and the project.json structure)
Install/uninstall scripts (related to the removal of the concept of install)
Content (related to install/uninstall, but work is in progress on this)
Content transforms (related to lack of install/uninstall)
I wish I had a more complete answer. But this is as far as I got once I discovered the PCL and how it evolved for the current infrastructure.
I'm in the process of creating a game creation toolkit that incorporates version control right off the bat. I want to be able to deploy a game as a Windows 10 app, or as a standard WPF app, but due to the libraries I'm using to integrate version control I need to create the editor as a standard WPF app. I had to be a bit creative in building the shared code and importing the correct libraries.
First, my project hierarchy:
Project.Model (Portable Class Library)
Project.Model.Versioning (standard C# library)
Mvvm.Toolkit (Portable Class Library)
Editor (Standard WPF application)
I want the core PCL to be able to load a project and deserialize the JSON encoded objects. The PCL did have access to System.IO, but surprisingly it is not the same as the one defined in the standard C# library. Here's how I had to fix things:
After adding the package reference to NewtonSoft.JSON, I had to change the target framework in the packages.config file:
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="portable-net452+win81" />
All projects dependent on my Project.Model class had to install the `system.io.filesystem' package from nuget so that the System.IO.FileInfo etc. objects were the same.
While this is definitely not a panacea, it's also not a dead end. I'm sure there are more gotchas, but this will at least help with some of the problems.
a .NET Standard library could be used to share a Model-View-ViewModel architecture between a WPF project and a UWP project.
https://www.syncfusion.com/ebooks/xamarin-forms-succinctly/sharing-code-among-platforms
https://devblogs.microsoft.com/dotnet/announcing-uwp-support-for-net-standard-2-0/

The type or namespace name 'IPAddress' could not be found

I'm writing a Xamarin.Forms application and have added a PCL project into my main solution in Visual Studio 2013. I'm having problems with using several standard .net classes. Here's a list:
System.Net.IPAddress
System.Net.IPEndPoint
System.Net.WebClient
System.Net.Sockets.UdpClient
System.Timers.Timer
System.Timers.ElapsedEventArgs
System.Net.NetworkInformation.UnicastIPAddressInformation
My question is: How do I figure out which of the above are compatable with a Xamarin.Forms app, and how do I get them to work in my project/solution?
I've contacted Xamarin support, but get vague help and not specifics...
Does anybody have a good strategy for figuring out what classes are supported and what .dlls are needed in order to use them with a Xamarin.Forms project?
Thanks a bunch for your help.
PS: I've been given the following sites for reference, but they don't seem to have any concise information:
What is supported
NuGet package info
It sounds like you don't understand what Portable Class Libraries actually are. When you create a PCL, the subset of the .Net Framework classes that are available for you to use depends on what profile you choose. A profile are the platforms your PCL can support. In Xamarin, the default profile is Profile 78. Profile 78 supports .NET 4.5, WP8, Win8, WP Silverlight 8, Win Store 8, Xamarin.Android, Xamarin.iOS. So the classes that are available to you are the classes that are platform independent, that run on ALL platforms in profile 78.
Example: Take a look at the implementation of System.Net.IPAddress. The implementation makes use of Sockets. Upon further inspection of this implementation, you can see that that System.Net.Sockets is nothing more than a .NET wrapper around the WinSock API. The WinSock API is a Windows only DLL that is specific to the Windows operating family (ws2_32.dll). So, you can now see that System.Net.IPAddress are high level abstractions of Windows Socks (built for the Windows Platform). Since the ws2_32.dll does not exist in Android, nor iOS, etc, this API won't be available to you because Profile 78 specifies that we need to support other non-windows platforms.
Another example is System.Drawing.Bitmap. That's just a .NET wrapper around GDI+, which is based on the Win32 API. Of course Win32 is not available on non-windows platforms (even Windows Phone), which is why you won't see it in a PCL.
Now with that being said, you may think that PCLs are restrictive, but you can create a good PCL library if you think about them the right way. You can also use patterns like Dependency Injection and Bait and Switch.
So in short, don't count on Microsoft "adding support for all the base class libraries" because that's not what PCLs are.
You can still use System.Net.IpAddress in your Xamarin.Forms PCL by using DependancyService. Make an interface in PCL and declare a method "GetIpAddress" in it. Then , in android /iOS project, you can implement that interface in platform specific project and easily access System.Net.IpAddress. After that, Call DependancyService from PCL project to get the result which is IPAddress of your desire.
Cheers !!!
After some additional e-mail from Xamarin Support, and comments on my additional posting, it appears that MS is quite behind in supporting all of their classes via PCL. Some are supported, but not all by a long shot.
Anyway, in order to use my existing code, I would need to put the source .cs files that I would otherwise be using to create my new PCL project directly in the .iOS project and in the .droid project and recompile that way.
This basically defeats the advantage of using a PCL, but does provide an alternative that allows me to use most of my code unchanged. It would just be nicer if all the xamarin libraries were available as PCLs.. Oh well, eventually MS will catch up and get all of their PCLs up to date so that we can use our custom PCLs more often, instead of having to duplicate code all over the place. (Maintenance Nightmare)...
Anyway, thanks to all for the help.
(Working on the bleeding edge of technology is sometimes painful... But that's why we make the big bucks !!!)

Expose C# classes in .net 4 class library to Silverlight App

I have a bunch of classes in a C# class library that I bought from a 3rd party company.
I want to use these classes and create my classes by inheriting them.
I have it all working on a .net 4 wpf application.
I want to then use these classes in my silverlight application.
What options do I have and which is the best option?
I want to use it in such a way that I can update the 3rd party company's DLL as they release their new version every month.
Just to re-inforce few points:
We have few options.
1. Link the classes (as an adding existing item but with a link)
2. Create interfaces and share them amongst WCF as a link class and let all classes inherit the interface
3. Use RIA service and let the web app create auto code to expose it to silverlight.
Are there other options? and if not then which one is better for the scenario that I am facing?
Thanks
It's worth noting however that the .NET platform shipping with Silverlight is not the same as the one shipping with the full .NET Framework.
It means that there is little chance that the third party assembly will be compatible with Silverlight, even if SL uses the same IL. If the third party assembly only references mscorlib or System.dll, it could be compiled as a cross platform assembly between SL and WPF.
However, in all the other cases, the differences between the SL and full .NET platform will prevent the assembly from being compatible with Silverlight.
If the third party software has anything to do with UI or network, if the software uses Windows API... etc.. it won't work in a Silverlight App.
This is the reason why a general .NET assembly can't be referenced from a SL project. However, there are cases when a SL assembly can be used in an general .NET project.
If the assembly perform computational and asynchronous task however, you could execute it on the server, and send back the result to the Silverlight app.
For instance it's a great option if the class Library generates reports, files or images.
What does the third party library do?
If you don't have the source code, you can't reference the class library in your Silverlight application (as you probably know already). It is not possible to use standard .NET libraries in Silverlight without recompiling, because Silverlight is a different framework and a different CLR.
You can use the library on the server and create some services to access the functionality.
I don't think there is any other way to achieve your goal, unless you get the source code which you can put into a directory with the name Shared. It will then be copied to your Silverlight application and compiled in Silverlight.

How to port a C#.net .dll to siverlight for more platform independence?

I have coded a dll library using the basic utilities of C#. But for platform independence, I want to port it to silverlight. Is it possible? If possible, then how to do it?
Or do you guys have any other suggestion?
If you build your DLL for Silverlight4, it can be referenced from a .NET-project; but not the other way round. See Sharing Silverlight Assemblies with .NET Apps.
Another method of sharing source code between SL and .Net is to use Linked files.
In your .net solution, add a silverlight library project.
Add>Existing Item>browse to the source files in the .net project, select them, click the little down-arrow on the 'add' button and select 'add as link'.
In a lot of cases, no modifications are necessary. In the instance that there is a minor discrepancy, use build flags and conditionals in source. e.g.
#if SILVERLIGHT
#else
#endif
This has worked out well for me, especially when I want to share a DTO library.
My suggestion is to create different project files (for .NET and SL). Then add the common files into each.
Many classes and methods are available on both .NET and SL, so it is possible to make the two projects share the same code.
This does not apply to all scenarios. For example, my open source project #SNMP uses UDP related classes, but SL does not have any UDP related things.
My personal choice is to limit the size of SL application and move necessary pieces into a backend WCF application.
What you need is a Portable Class Library: http://msdn.microsoft.com/en-us/library/gg597391.aspx
This way can share a project/DLL between .Net, Silverlight and Windows Phone projects.

Categories