可移植类库和WebBrowserTask与Windows.System.Launcher

时间:2013-07-30 09:59:08

标签: c# windows-store-apps launcher portable-class-library

我假设答案完全没有,但为了以防万一......有没有办法在PCL中执行特定于平台的代码?

我的具体例子非常适合PCL。使用profile104(WP7 / Windows Store / Net40)完全支持绝大多数代码。平台特定的唯一一点是能够启动深层链接:

my-custom-protocol://some/url

非共享代码是:

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.

因此,公共库提供了自定义“Task”对象,它们提供了“BuildUrl()”的实现。问题是,在受支持的设备上,您希望启动“my-custom-protocol:// some / url”,但在任何其他设备上,您要启用网络后备http://mysite.com/some/url。这一切都包含在:

        new CustomTask(data).Show()
  • 选项1(当前实现):不要使用PCL,并在CustomTaskBase类中使用#ifdefs来包含平台细节。但是,我真的不希望维护平台特定的项目文件,并将cs文件添加为链接: - (

  • 选项2:将启动器放在特定于平台的程序集中,将所有其他代码放在PCL中。同样,我不喜欢这样,因为它看起来很重,并没有减少我们的项目数量。这也意味着客户需要引用两个程序集,而不是一个程序集,这对于一些自定义任务来说似乎有些过时了。

  • 选项3:将抽象的IPlatformSpecificLauncher注入Launcher的构造函数,然后该构造函数成为URLBuilder。这会将启动代码移动到客户端,这将是复制粘贴(尽管很小)。但它确实使API复杂化并使其可读性降低。

        new CustomTask(new WP8Launcher(), data).Show()
    
  • 选项4:更改API,以便CustomTask只返回要启动的URL(并再次在客户端中启动启动代码)。但是,如何在不支持自定义协议的设备上实现Web回退?你不能说PCL中是否(平台== WP7),你呢?

提前感谢您的任何提示和提示!

1 个答案:

答案 0 :(得分:5)

对于PCL中与平台相关的功能,明显的答案(除了放弃)是某种依赖注入,或使用服务定位器。在我看来,你的例子很好地利用了DI,甚至忽略了PCL的实际限制 - 你真的在插入不同的行为。

“平台启蒙”ala RX是另一种方法(对所有这些方法的良好概述here),其中PCL通过反射加载其他组件。

在任何一种情况下,您都会增加项目数量。我认为有一个论点是尽可能多地将PCL放入PCL并将特定于平台的功能分离成单独的小块比从多个项目链接的大型共享库更清晰,其中共享和#if-条件代码之间的区别不太明显。

关于“你能说if(platform == WP7)”这个问题,你的PCL不能包含平台条件代码,尽管PCL可以定位所有包含所需功能的平台子集。