Portable class libraries and WebBrowserTask vs Windows.System.Launcher

I guess the answer is simply no, but just in case ... Is there a way to execute platform-specific code in PCL?

My specific example is good for PCL. The vast majority of codes are fully supported using profile104 (WP7 / Windows Store / Net40). The only bit that is platform specific is the ability to launch a deep link:

my-custom-protocol://some/url 

Non-shared code:

 On WP7, it would be: WebBrowserTask web = new WebBrowserTask(); web.Uri = BuildUrl(); web.Show(); On WP8 and Windows Store it would be: Windows.System.Launcher.LaunchUriAsync(BuildUrl()); On Net40, I guess you would host a web-browser control. 

Thus, the shared library provides custom Task objects that provide an implementation of BuildUrl (). The problem is that on a supported device you want to run "my-custom-protocol: // some / url", but on any other device you want to go to the backup system http://mysite.com/some/url . All this is wrapped in:

  new CustomTask(data).Show() 
  • Option 1 (Current implementation): do not use PCL and use #ifdefs in the CustomTaskBase class to contain platform specifics. However, I really don't want to support platform-specific project files, with cs files added as links: - (

  • Option 2: just put the launchers on prefabricated platforms, with all the other code in the PCL. Again, I do not like this, because it seems like a heavy maintenance and does not reduce the number of projects. This also means that clients need to reference two assemblies, not one, which seems redundant for several user tasks.

  • Option 3: Embed the abstract IPlatformSpecificLauncher in the Launcher constructor, which will then become the URLBuilder. This moves the startup code to the client, which will copy-paste (albeit minimal). However, it complicates the API and makes it less readable.

      new CustomTask(new WP8Launcher(), data).Show() 
  • Option 4: Change the API so that CustomTask simply returns the URL to run (and again has a built-in launch code). But then how would you implement web backup on devices that do not support their own protocol? You cannot say if (platform == WP7) in PCL, can you?

Thank you for any tips and tricks!

+4
source share
1 answer

For platform-specific functionality in PCL, the obvious answer (other than failure) is to inject some type of dependency or use a service locator. Your example, in my opinion, is a good use of DI in general, even ignoring the actual limitations of PCL - you are really connecting to a different behavior.

The ala RX “enlightenment platform” is another approach (a good overview of all of these approaches here ), where the PCL loads additional assemblies through reflection.

In any case, you will increase the number of projects. I think that there is an argument that the maximum possible use of PCL and the separation of platform functionality into separate small fragments is cleaner than a large shared library that is associated with several projects, where the difference between general and # if-conditional code is less obvious.

Regarding the question “can you say if (platform == WP7)”, your PCL cannot contain conditional code, although the PCL can target a subset of platforms, all of which contain the required functionality.

+5
source

Source: https://habr.com/ru/post/1494242/


All Articles