可移植类库和Web浏览器任务与Windows.System.Launcher



我假设答案是否定的,但只是以防万一。。。有没有任何方法可以在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()"的实现。问题是,在受支持的设备上,您希望启动"我的自定义-protocol://some/url",但在任何其他设备上,您都希望转到web回退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回退?你不能说如果(平台==WP7)在PCL,是吗?

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

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

"平台启蒙"ala RX是另一种方法(此处对所有这些方法进行了很好的概述),PCL通过反射加载额外的组件。

无论哪种情况,你都会增加你的项目数量。我认为有一种观点认为,在PCL中投入尽可能多的内容,并将特定于平台的功能分离成单独的小块,比从多个项目链接的大型共享库更干净,在那里,共享代码和#if条件代码之间的区别不太明显。

至于"你能说如果(platform==WP7)"这个问题,你的PCL不能包含平台条件代码,尽管PCL可以针对所有包含所需功能的平台的子集。

最新更新