c# - 有什么方法可以在UWP应用程序和WPF应用程序之间共享代码?

标签 c# wpf mvvm uwp

明确地说,我遵循MVVM模式,并且我希望对项目进行结构设计,以便可以在UWP应用程序和标准WPF应用程序之间共享模型代码。我要共享的代码没有UI。我不喜欢寻找新工具来代替我多年来使用的工具,这些工具可以处理某些任务,例如日志记录,连接到面向文档的数据库等。

我试图开始围绕已有的一些代码编写UWP包装器,并直接引用模型项目。 Visual Studio拒绝让这种情况发生,向我显示了一条错误消息,内容为“无法添加对项目'ACK.Model'的引用”。当我尝试将模型放入通用库并从WPF应用程序引用它时,发生了同样的事情。我不是在尝试共享WPF代码。只是没有引用UI库的模型层。

这是一个令人恐惧的主张,因为这意味着如果我想做很多实质性的事情,我必须选择跳到UWP的100%或保持WPF的100%。 NewtonSoft.JSON可能具有通用发行版(ASP.NET MVC),但是ElasticSearch.NET和其他用于制作重要应用程序的工具又如何呢?

我发现“便携式类库”项目类型隐藏在哪里。 PCL将使我可以在WPF和Universal应用程序之间共享代码,因为这是一种选择。这解决了我的代码中Model部分的简单情况,但我(仍然)无法使用我想要的某些库。我仍然需要大量没有PCL的库。

最佳答案

大约一年后,随着Visual Studio 2017的到来,出现了一个更完整的解决方案。如果将库指定为.Net Standard,则该库与.Net Core应用程序和整体式.Net目标应用程序兼容。对标准.Net库和API的支持以及对现代C#语言功能的支持都相当完整。

现在的一般建议是:

  • 所有库的目标.Net标准
  • 为您的实际应用程序定位适当的平台。 (UWP或WPF)。

  • 注意:如果您的库必须与C库或应用程序进行交互,则必须格外小心,以确保加载正确的版本。

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

    在Visual Studio 2015中创建PCL时,可以指定希望从以下位置访问的API的类型:
  • 通用应用程序
  • 单声道
  • .Net Core 5
  • .Net 4.6

  • 当然,这限制了您可以使用的API,但是只要与UI不相关,您要使用的大多数API都是可以的。还有其他限制:
  • 您的项目只能在Visual Studio 2015或更高版本中进行编辑
  • 您无权从Environment变量访问特殊目录(即,用户Documents目录等)。
  • 您不能链接到仅为您的目标平台之一(例如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等对象相同。

  • 尽管这绝对不是万能药,但这也不是死胡同。我敢肯定还有更多的陷阱,但这至少可以帮助解决一些问题。

    关于c# - 有什么方法可以在UWP应用程序和WPF应用程序之间共享代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34913488/

    相关文章:

    c# - 从 View X 中的 ListView 选择填充 View Y 时,为什么 View Y 显示陈旧的结果?

    c# - CsvHealper - 如何忽略 csv 中的空列

    c# - 如何在 RichTextBox 中的文本上正确应用背景色

    WPF 嵌套样式

    wpf - MVVM:处理集合中模型的逻辑子对象

    c# - 通过 WPF 命令模式启用提交/取消按钮

    mvvm - 使用 TPL 时如何在 UI 线程上调用方法?

    c# - IOException: 进程无法访问文件 'file path',因为它正被另一个进程使用

    c# - 如何在devexpress的布局 View (gridcontrol)中添加按钮

    wpf - Visual Studio 2010 WPF/Silverlight 设计器默认背景