4

我假设答案是否定的,但以防万一……有没有办法在 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.

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

        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-fallback?您不能在 PCL 中说 if(platform == WP7),可以吗?

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

4

1 回答 1

5

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

“平台启蒙”ala RX 是另一种方法(此处对所有这些方法进行了很好的概述),其中 PCL 通过反射加载其他程序集。

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

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

于 2013-07-30T11:41:12.307 回答