有没有办法在 UWP 应用和 WPF 应用之间共享代码?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34913488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there any way to share code between UWP apps and WPF apps?
提问by Berin Loritsch
To be clear, I follow the MVVM pattern, and I want to structure my project such that I can share my model code between a UWP app and a standard WPF app. The code I want to share has no UI. I don't relish the thought of finding new tools to replace the ones that I've been using for years that take care of certain tasks like logging, connecting to a document oriented database, etc.
明确地说,我遵循 MVVM 模式,并且我想构建我的项目,以便我可以在 UWP 应用程序和标准 WPF 应用程序之间共享我的模型代码。我想分享的代码没有 UI。我不喜欢寻找新工具来替换我多年来一直在使用的工具来处理某些任务,例如日志记录、连接到面向文档的数据库等。
I attempted to start writing a UWP wrapper around some code I already have and reference the model project directly. Visual Studio refused to let that happen, showing me an error message that says "Unable to add a reference to project 'ACK.Model'". The same thing happened when I attempted to put the model in a Universal Library and reference it from a WPF app. I'm not trying to share WPF code. Just the model layer that has no reference to UI libraries.
我试图开始围绕我已有的一些代码编写 UWP 包装器,并直接引用模型项目。Visual Studio 拒绝让这种情况发生,向我展示了一条错误消息,内容为“无法添加对项目 'ACK.Model' 的引用”。当我尝试将模型放入通用库并从 WPF 应用程序引用它时,发生了同样的事情。我不是要分享 WPF 代码。只是没有引用 UI 库的模型层。
This is a scary proposition, because it means that if I want to do anything substantial I have to choose to either jump 100% to UWP or stay 100% WPF. NewtonSoft.JSON might have a universal distribution (ASP.NET MVC), but what about ElasticSearch.NET, and other tools needed to make important apps?
这是一个可怕的提议,因为这意味着如果我想做任何实质性的事情,我必须选择 100% 跳到 UWP 或保持 100% WPF。NewtonSoft.JSON 可能有一个通用的发行版 (ASP.NET MVC),但是 ElasticSearch.NET 和其他制作重要应用程序所需的工具呢?
I found where the "Portable Class Library" project type was hiding. PCLs will allow me to share mycode across WPF and Universal apps as that was one of the options. This solves the simple case of the Model part of my code, but I (still) can't use some of the libraries I want. There are still a large number of libraries that I need that do not have PCL available.
我找到了“便携式类库”项目类型的隐藏位置。PCL 将允许我在 WPF 和通用应用程序之间共享我的代码,因为这是选项之一。这解决了我的代码模型部分的简单情况,但我(仍然)无法使用我想要的一些库。我仍然需要大量没有 PCL 的库。
回答by Berin Loritsch
About a year later, with the advent of Visual Studio 2017 there is a more complete solution. If you target your libraries to .Net Standardthen the library is compatible with both .Net Coreapps and the monolithic .Nettargeted app. The support for standard .Net libraries and APIs is fairly complete, as is the support for modern C# language features.
大约一年后,随着 Visual Studio 2017 的出现,出现了更完整的解决方案。如果您将库定位到.Net Standard,则该库与.Net Core应用程序和单体.Net目标应用程序兼容。对标准 .Net 库和 API 的支持相当完整,对现代 C# 语言功能的支持也是如此。
The general advice now is this:
现在的一般建议是:
- Target .Net Standardfor all libraries
- Target the appropriate platform for your actual application. (UWP or WPF).
- 所有库的目标.Net 标准
- 为您的实际应用选择合适的平台。(UWP 或 WPF)。
NOTE: if your library has to interact with C libraries or applications, you have to take extra care to make sure you load the correct version.
注意:如果您的库必须与 C 库或应用程序交互,则必须格外小心以确保加载正确的版本。
It appears that there is a solution, but it has to be adopted by the whole tool chain you want to use. When Microsoft introduced Windows Store apps in Windows 8, they also introduced a Portable Class Library (PCL). The purpose of the PCL is to share code between different parts of your application.
似乎有一个解决方案,但它必须被您要使用的整个工具链采用。当 Microsoft 在 Windows 8 中引入 Windows Store 应用程序时,他们还引入了一个可移植类库 (PCL)。PCL 的目的是在应用程序的不同部分之间共享代码。
When you create a PCL in Visual Studio 2015, you can specify the types of APIs you want it to be accessible from:
当您在 Visual Studio 2015 中创建 PCL 时,您可以指定您希望它可以访问的 API 类型:
- Universal Apps
- Mono
- .Net Core 5
- .Net 4.6
- 通用应用
- 单核细胞增多症
- .Net 核心 5
- .Net 4.6
This of course, limits the APIs available to you but most of the ones you want to use are OK as long as it's not UI related. There are other limitations as well:
这当然会限制您可用的 API,但只要与 UI 无关,大多数您想使用的 API 都可以。还有其他限制:
- Your project can only be edited in Visual Studio 2015 or greater
- You don't have access to special directories from the Environment variable (i.e. user Documents directory, etc.)
- You can't link to a library designed for only one of your target platforms (i.e. libgit2sharp, etc.)
There's no way to browse the API for this subset--MSDN needs to get on the stick.MSDN has updated much of the API documentation, but it's still difficult to figure out what applies to your PCL
- 您的项目只能在 Visual Studio 2015 或更高版本中编辑
- 您无权从 Environment 变量(即用户 Documents 目录等)访问特殊目录
- 您不能链接到仅为您的目标平台之一设计的库(即 libgit2sharp 等)
没有办法浏览这个子集的 API——MSDN 需要坚持下去。MSDN 已经更新了大部分 API 文档,但仍然很难弄清楚哪些内容适用于您的 PCL
However, you can link any library designed for a single target platform to your PCL. It's not ideal, but it's better than nothing.
但是,您可以将任何为单一目标平台设计的库链接到您的 PCL。这并不理想,但总比没有好。
The ASP.NET MVC stack has been ported to using PCLs, so you can use NewtonSoft.JSON directly as well as any other of those libraries used by that application. However, there are several libraries that have not been ported.
ASP.NET MVC 堆栈已移植到使用 PCL,因此您可以直接使用 NewtonSoft.JSON 以及该应用程序使用的任何其他库。但是,有几个库尚未移植。
This arrangement forces you to think about how you want to integrate better. The .Net Core 5 seems to be stable, but support is in it's infancy. The current generation of Universal Apps as of VS 2015 update 1 uses .Net Core 5 directly.
这种安排迫使您考虑如何更好地整合。.Net Core 5 似乎很稳定,但支持还处于起步阶段。从 VS 2015 更新 1 开始,当前这一代通用应用程序直接使用 .Net Core 5。
There are several features from Nuget that are not currently supported even though work is under way:
尽管工作正在进行中,但目前不支持 Nuget 的一些功能:
- MS Build extensions (major changes to MSBuild and the project.json structure)
- Install/uninstall scripts (related to the removal of the concept of install)
- Content (related to install/uninstall, but work is in progress on this)
- Content transforms (related to lack of install/uninstall)
- MS Build 扩展(对 MSBuild 和 project.json 结构的重大更改)
- 安装/卸载脚本(与去除安装概念有关)
- 内容(与安装/卸载相关,但工作正在进行中)
- 内容转换(与缺少安装/卸载有关)
I wish I had a more complete answer. But this is as far as I got once I discovered the PCL and how it evolved for the current infrastructure.
我希望我有一个更完整的答案。但这就是我发现 PCL 以及它如何针对当前基础设施发展后得到的。
I'm in the process of creating a game creation toolkit that incorporates version control right off the bat. I want to be able to deploy a game as a Windows 10 app, or as a standard WPF app, but due to the libraries I'm using to integrate version control I need to create the editor as a standard WPF app. I had to be a bit creative in building the shared code and importing the correct libraries.
我正在创建一个立即包含版本控制的游戏创建工具包。我希望能够将游戏部署为 Windows 10 应用程序或标准 WPF 应用程序,但由于我用于集成版本控制的库,我需要将编辑器创建为标准 WPF 应用程序。在构建共享代码和导入正确的库时,我必须有点创意。
First, my project hierarchy:
首先,我的项目层次结构:
- Project.Model (Portable Class Library)
- Project.Model.Versioning (standard C# library)
- Mvvm.Toolkit (Portable Class Library)
- Editor (Standard WPF application)
- Project.Model(可移植类库)
- Project.Model.Versioning(标准 C# 库)
- Mvvm.Toolkit(可移植类库)
- 编辑器(标准 WPF 应用程序)
I want the core PCL to be able to load a project and deserialize the JSON encoded objects. The PCL did have access to System.IO, but surprisingly it is not the same as the one defined in the standard C# library. Here's how I had to fix things:
我希望核心 PCL 能够加载项目并反序列化 JSON 编码的对象。PCL 确实可以访问System.IO,但令人惊讶的是它与标准 C# 库中定义的不同。这是我必须解决的问题:
After adding the package reference to NewtonSoft.JSON, I had to change the target framework in the
packages.configfile:<package id="Newtonsoft.Json" version="8.0.2" targetFramework="portable-net452+win81" />All projects dependent on my Project.Model class had to install the `system.io.filesystem' package from nuget so that the System.IO.FileInfo etc. objects were the same.
添加对 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 等对象是相同的。
While this is definitely not a panacea, it's also not a dead end. I'm sure there are more gotchas, but this will at least help with some of the problems.
虽然这绝对不是灵丹妙药,但也不是死胡同。我敢肯定还有更多问题,但这至少会帮助解决一些问题。
回答by Leszek P
a .NET Standard library could be used to share a Model-View-ViewModel architecture between a WPF project and a UWP project.
.NET Standard 库可用于在 WPF 项目和 UWP 项目之间共享模型-视图-视图模型架构。
https://www.syncfusion.com/ebooks/xamarin-forms-succinctly/sharing-code-among-platformshttps://devblogs.microsoft.com/dotnet/announcing-uwp-support-for-net-standard-2-0/
https://www.syncfusion.com/ebooks/xamarin-forms-succinctly/sharing-code-among-platforms https://devblogs.microsoft.com/dotnet/announcing-uwp-support-for-net-standard-2 -0/

