有没有办法在UWP应用和WPF应用之间共享代码?

11
需要明确的是,我遵循MVVM模式,并希望结构化我的项目以便可以在UWP应用和标准WPF应用之间共享我的模型代码。 我想要分享的代码没有UI。 我不喜欢想到必须找到新的工具来代替我多年来使用的那些负责某些任务(如日志记录、连接文档导向数据库等)的工具。
我尝试编写一个UWP包装器来包装我已有的一些代码并直接引用模型项目。 然而Visual Studio拒绝了这个操作,并显示错误消息:“无法添加对项目“ACK.Model”的引用”。 当我试图将模型放入通用库并从WPF应用中进行引用时,同样的事情发生了。 我不想共享WPF代码,只是模型层没有引用UI库。
这是一个可怕的问题,因为它意味着如果我想要做任何实质性的事情,我必须选择全面转向UWP或者完全停留在WPF。NewtonSoft.JSON可能有一个通用分布(ASP.NET MVC),但ElasticSearch.NET以及其他使重要应用程序运行所必需的工具呢?
我找到了“可移植类库”项目类型隐藏的地方。PCL(Portable Class Library)能够允许我在WPF和通用应用之间共享我的代码,因为其中有此选项。这解决了我代码中模型部分的简单情况,但是我仍然不能使用我想要的一些库。仍然有很多我需要用到的库没有PCL可用。

1
欢迎来到我们的困境,我的朋友。目前来看,我认为还没有。在UWP对我们开放之后,我们尝试过搜索这个功能。目前我们仍然依赖WebAPI来实现它。共享代码并将其重用作为可重用代码是一种解决方案,但目前并没有帮助。因为UWP仍然专注于Windows家族应用程序,而不是ASP Web应用程序。这两种结构实现起来有很大的差异,如果您找到了解决方法,请在您的问题中重新发布。 - Aizen
你需要对使用第三方库的代码进行抽象,然后将它们替换为适用于WPF/UWP的库。例如,你可以使用 IJsonProvider 接口来代替直接使用 NewtonSoft.JSON 库。在UWP中,你可以使用微软的Json堆栈,在WPF中则可以使用JsonSoft等库。 - Tseng
投票关闭此问题的人,能否详细说明为什么您觉得这不是主题。这不是关于计算机的一般性问题,而是关于在不同的C#平台之间共享代码的问题。 - Berin Loritsch
请查看此处 https://learn.microsoft.com/zh-cn/dotnet/standard/frameworks - Joaquín Luis Monleón Irisarri
@JoaquínLuisMonleónIrisarri,当NetStandard还不存在时,我曾经问过这个问题。在NetStandard可用后,我也更新了我的答案,而且现在的情况只会更好。 - Berin Loritsch
2个回答

15

大约一年后,随着Visual Studio 2017的推出,有了更完整的解决方案。如果将您的库目标定为.Net Standard,则该库与.Net Core应用程序和单片的.Net应用程序均兼容。对于标准的.Net库和API提供了相当完整的支持,同时还支持现代C#语言特性。

现在的一般建议是:

  • 针对所有库使用.Net Standard
  • 针对实际应用程序选择适当的平台(UWP或WPF)。

注意:如果您的库必须与C库或应用程序进行交互,则必须仔细确保加载正确的版本。


看来有一个解决方案,但它必须被您想要使用的整个工具链所采纳。当Microsoft在Windows 8中引入Windows Store应用程序时,他们也引入了一个可移植类库(Portable Class Library, PCL)。PCL的目的是在应用程序的不同部分之间共享代码。

在Visual Studio 2015中创建PCL时,您可以指定希望从中访问的API类型:

  • 通用应用程序
  • Mono
  • .Net Core 5
  • .Net 4.6

当然,这会限制您可用的API,但只要与UI无关,您想使用的大多数API都可以。还有其他限制:

  • 您的项目只能在Visual Studio 2015或更高版本中进行编辑
  • 您无法访问来自环境变量的特殊目录(即用户文档目录等)
  • 您无法链接到仅为一个目标平台设计的库(即libgit2sharp等)
  • 没有浏览此子集的API的方法——MSDN需要加紧更新。 MSDN已经更新了很多API文档,但找出适用于您的PCL的内容仍然很困难。
  • 不过,您可以将任何为单个目标平台设计的库链接到您的PCL中。虽然这并不是理想的解决方案,但总比没有好。

    ASP.NET MVC堆栈已经被移植到使用PCL,因此您可以直接使用NewtonSoft.JSON以及该应用程序使用的任何其他库。然而,还有几个库没有被移植。

    这种安排迫使您考虑如何更好地集成。.Net Core 5似乎很稳定,但支持处于起步阶段。截至VS 2015更新1时的当前一代通用应用程序直接使用.Net Core 5。

    尽管正在进行工作,但现在还不支持Nuget的几个功能:

    • MS Build扩展(对MSBuild和project.json结构的重大更改)
    • 安装/卸载脚本(与安装概念的删除相关)
    • 内容(与安装/卸载相关,但正在进行此项工作)
    • 内容转换(与缺少安装/卸载有关)

    我希望我有一个更完整的答案。但这是我在发现PCL及其为当前基础设施演变的方式后所得到的结论。


    我正在创建一个游戏创作工具包,其中包含版本控制功能。我希望能够将游戏部署为Windows 10应用程序或标准的WPF应用程序,但由于我使用的库需要集成版本控制,因此我需要将编辑器创建为标准的WPF应用程序。在构建共享代码并导入正确的库时,我必须有些有创意。

    首先,我的项目层次结构:

    • Project.Model (可移植类库)
    • Project.Model.Versioning(标准的C#库)
    • Mvvm.Toolkit(可移植类库)
    • 编辑器(标准的 WPF 应用程序)

    我希望核心 PCL 能够加载项目和反序列化 JSON 编码的对象。PCL 之前可以访问 System.IO,但令人惊讶的是它与标准 C# 库中定义的不同。以下是我解决问题的方法:

    • 在添加了 NewtonSoft.JSON 的软件包引用后,我不得不更改 packages.config 文件中的目标框架:

      <package id="Newtonsoft.Json" version="8.0.2" targetFramework="portable-net452+win81" />

    • 所有依赖于我的 Project.Model 类的项目都必须从 nuget 安装 `system.io.filesystem' 包,以便 System.IO.FileInfo 等对象相同。

    虽然这肯定不是万能药,但也不是死路一条。我相信还有更多需要注意的地方,但至少可以解决一些问题。



    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接