如何减少特定于平台的项目之间的代码重复量?

How can I reduce the amount of code duplication between my platform-specific projects?

我正在研究 Xamarin.Forms 解决方案,它使用 PCL 库在我的 Android 和 iOS 项目之间共享代码。这在大多数情况下都非常有效,因为大多数 UI 和逻辑代码都可以保存在一个地方。当然,我创建了一些特定于平台的 类,并使用 DependencyService 链接到 PCL,这对大多数 类 来说都很好,因为平台之间的代码明显不同(例如 UI layout/appearance)。

但是,类 的一个子集使用了 PCL 项目无法使用的各种命名空间(特别是 System.Data 命名空间)。为了绕过这个限制,我不得不为每个 类 编写一个 DependencyService。我担心的是 Android 和 iOS 之间的代码完全相同,减去一两行。代码非常复杂,我不想在需要时记得更新它两次

考虑到由于必要的命名空间不可用,我无法将代码放入 PCL,有没有办法可以减少这两个项目之间重复的代码量?

我能够使用共享项目消除所有重复代码(正如@matthewrdev 所建议的)。不过,这个过程比我预期的要复杂一些,所以我会添加一个关于我所做的事情的指南。

  1. 创建一个新的 Xamarin.Forms 共享项目。 (不幸的是,我只能选择创建一个 "blank app (shared)" 项目,它带有预生成的 Android 和 iOS 项目。我删除了那些,因为我已经有了必要的平台项目。)

  2. 将所有重复的代码添加到共享项目中。您可能需要更新命名空间。对于需要 运行 特定于平台的任何代码,您必须使用 #if __ANDROID__#if __IOS__ 预处理器指令。

  3. 在您的平台项目中添加对共享项目的引用(在我的例子中,Android 和 iOS)。在 VS2013 中,这有点复杂,因为您(显然)无法添加对共享项目的引用。您要么必须手动修改 .csproj 文件(请参阅 VS2013 的 this answer for details) or you can use the Shared Project Reference Manager 扩展名。

  4. 确保将 __ANDROID____IOS__ 条件编译符号添加到您的平台项目。为此,您需要打开项目的属性,转到 "Build" 选项卡,然后在显示 "conditional compilation symbols" 的位置添加符号。

这些说明适用于 Visual Studio 2013,但 Xamarin Studio 和 VS2015 的步骤类似。

我建议在您的体系结构中插入一个共享项目。我将继续使用由接口抽象的平台 类,用于需要依赖于平台的代码 and/or 使用平台 API。但是,如果您有可以在这些平台 类 之间共享的代码,您可以将该代码放在共享项目中并让平台 类 引用它。

我以前在 SQlite Access 中使用过这种模式。我需要低级别 ADO.net 支持,这意味着手动将数据映射到 SqliteDataReader 之外。这样做的逻辑在平台之间很常见,但不能进入 PCL。所以我有一个用于数据映射的 SharedProject,我的平台数据库实现引用了该项目。

请参阅下面的示例 class 图。