在UWP应用程序和WPF应用程序之间是否存在共享代码的方法?

时间:2023-01-24 13:05:20

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应用程序之间共享我的模型代码。我不喜欢寻找新的工具来取代我多年来一直使用的工具,这些工具可以处理某些任务,比如日志记录、连接到面向文档的数据库等等。

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应用程序中引用时,也发生了同样的事情。只有模型层没有对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),但是关于弹性搜索呢?NET和其他制作重要应用程序所需的工具?


I found where the "Portable Class Library" project type was hiding. PCLs will allow me to share my code 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.

我找到了“可移植类库”项目类型隐藏的地方。PCLs将允许我在WPF和Universal应用程序*享我的代码,因为这是一个选项。这解决了我代码模型部分的简单情况,但是我(仍然)不能使用我想要的一些库。还有大量的库是我需要的,没有PCL可用。

1 个解决方案

#1


12  

About a year later, with the advent of Visual Studio 2017 there is a more complete solution. If you target your libraries to .Net Standard then the library is compatible with both .Net Core apps and the monolithic .Net targeted 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标准为目标,那么这个库就可以兼容。net核心应用程序和。net整体目标应用程序。

The general advice now is this:

目前的一般建议是:

  • Target .Net Standard for all libraries
  • 针对所有库的。net标准
  • Target the appropriate platform for your actual application. (UWP or WPF).
  • 为您的实际应用程序寻找合适的平台。(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.

似乎有一个解决方案,但它必须被您想要使用的整个工具链所采用。当微软在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
  • 5 . net核心
  • .Net 4.6
  • 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
  • 您的项目只能在Visual Studio 2015或更高版本中编辑
  • 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.)
  • 不能链接到只为目标平台之一设计的库(例如libgit2sharp等)。
  • 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
  • 没有办法浏览这个子集的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栈已经被移植到使用PCLs,所以您可以使用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核心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)
  • MS构建扩展(对MSBuild和项目的主要更改)。json结构)
  • 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)
  • 内容转换(与缺少安装/卸载有关)

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.

我正在创建一个游戏创建工具箱,该工具箱立即集成了版本控制。我希望能够部署10游戏作为Windows应用程序,或作为一个标准WPF应用程序,但是由于我使用集成版本控制库需要创建编辑器作为标准WPF应用程序。我不得不有点创造性地构建共享代码和导入正确的库。

First, my project hierarchy:

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

  • Project.Model (Portable Class Library)
  • 项目。模型(便携类库)
  • Project.Model.Versioning (standard C# library)
  • Project.Model。版本控制(标准c#库)
  • Mvvm.Toolkit (Portable Class Library)
  • Mvvm。工具包(便携类库)
  • Editor (Standard WPF application)
  • 编辑器(标准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确实可以访问系统。IO,但令人惊讶的是它与标准c#库中定义的不一样。我要做的就是:

  • After adding the package reference to NewtonSoft.JSON, I had to change the target framework in the packages.config file:

    将包引用添加到NewtonSoft后。JSON,我必须修改包中的目标框架。配置文件:

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

    <包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.

    所有项目都依赖于我的项目。Model类必须安装' system.io。文件系统的包,从nuget到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.

虽然这绝对不是万灵药,但也不是死胡同。我肯定还有更多的问题,但这至少有助于解决一些问题。

#1


12  

About a year later, with the advent of Visual Studio 2017 there is a more complete solution. If you target your libraries to .Net Standard then the library is compatible with both .Net Core apps and the monolithic .Net targeted 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标准为目标,那么这个库就可以兼容。net核心应用程序和。net整体目标应用程序。

The general advice now is this:

目前的一般建议是:

  • Target .Net Standard for all libraries
  • 针对所有库的。net标准
  • Target the appropriate platform for your actual application. (UWP or WPF).
  • 为您的实际应用程序寻找合适的平台。(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.

似乎有一个解决方案,但它必须被您想要使用的整个工具链所采用。当微软在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
  • 5 . net核心
  • .Net 4.6
  • 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
  • 您的项目只能在Visual Studio 2015或更高版本中编辑
  • 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.)
  • 不能链接到只为目标平台之一设计的库(例如libgit2sharp等)。
  • 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
  • 没有办法浏览这个子集的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栈已经被移植到使用PCLs,所以您可以使用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核心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)
  • MS构建扩展(对MSBuild和项目的主要更改)。json结构)
  • 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)
  • 内容转换(与缺少安装/卸载有关)

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.

我正在创建一个游戏创建工具箱,该工具箱立即集成了版本控制。我希望能够部署10游戏作为Windows应用程序,或作为一个标准WPF应用程序,但是由于我使用集成版本控制库需要创建编辑器作为标准WPF应用程序。我不得不有点创造性地构建共享代码和导入正确的库。

First, my project hierarchy:

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

  • Project.Model (Portable Class Library)
  • 项目。模型(便携类库)
  • Project.Model.Versioning (standard C# library)
  • Project.Model。版本控制(标准c#库)
  • Mvvm.Toolkit (Portable Class Library)
  • Mvvm。工具包(便携类库)
  • Editor (Standard WPF application)
  • 编辑器(标准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确实可以访问系统。IO,但令人惊讶的是它与标准c#库中定义的不一样。我要做的就是:

  • After adding the package reference to NewtonSoft.JSON, I had to change the target framework in the packages.config file:

    将包引用添加到NewtonSoft后。JSON,我必须修改包中的目标框架。配置文件:

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

    <包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.

    所有项目都依赖于我的项目。Model类必须安装' system.io。文件系统的包,从nuget到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.

虽然这绝对不是万灵药,但也不是死胡同。我肯定还有更多的问题,但这至少有助于解决一些问题。