编译UWP应用程序时出现错误:"使用Windows命名空间是保留的。"

8
我正在为Windows 10创建一个UWP应用程序,使用语音API,但编译时出现奇怪的错误。情况如下:
一个针对Windows 8.1的PCL项目(在创建项目时将Windows 10设置为目标,但Visual Studio会降级为Windows 8.1,因为“它们支持相同的便携式API集”),并引用了“Windows.Foundation.UniversalApiContract”,因为它包含语音API(Windows.Media.SpeechRecognition和Windows.Media.SpeechSynthesis);
一个UWP应用程序,引用了PCL项目,该UWP不使用语音API,我仅在PCL项目中使用它。
PCL项目已经成功构建,但当我构建UWP项目时,会出现很多错误,比如“Windows.Foundation.UniversalApiContract.winmd文件包含类型‘XXXXX’。使用Windows命名空间是保留的。”我认为这个错误是由于PCL项目的引用引起的。
我试图直接从UWP应用程序调用语音API,似乎可以工作,但我不喜欢这样做,因为我更喜欢将应用程序逻辑放在其他库项目中,以防将应用程序移植到其他平台。
我不知道该怎么办。如果PCL针对Windows 8.1,则必须能够在没有像在UWP项目中添加引用的情况下使用语音API,对吗?有没有解决方法来强制PCL仅针对Windows 10?我错了,应该使用其他项目类型而不是PCL吗?
2个回答

7

您不能在PCL中引用Windows.Foundation.UniversalApiContract。因为它是一个便携式类库,不能引用仅限于Windows的库。要使用Windows API,您需要拥有Windows通用类库或Windows通用运行时组件。

由于您想要使应用程序可移植,您需要选择不同的方法,使用依赖注入。

便携式类库应该只包含平台无关的代码。因为语音API显然不是跨平台的(每个操作系统都有自己的实现,每个实现都非常不同),您需要在PCL中只定义一个接口,然后在您的平台项目中提供实现。

它如何工作?

为了简单起见,假设您只想使用语音合成(对于语音识别,解决方案是类似的)。

首先,在您的PCL中创建一个ISpeechSynthesisService接口:

public interface ISpeechSynthesisService
{
    Task SynthesizeTextAsync( string text );
}

现在,您需要在UWP项目中提供一个实现:
public class WindowsSpeechSynthesisService : ISpeechSynthesisService
{
    public Task SynthesizeTextAsync( string text )
    {
        //implementation
    }
}

由于您可能希望在PCL项目中使用该服务(例如在ViewModel中),因此您现在可以受益于使用依赖注入容器。大多数MVVM框架已经提供了这个功能(如Template 10、MvvmLight、MvvmCross、Prism等)。DI容器允许您为给定接口注册实现并创建它们的实例。因此,在UWP项目中,您可以执行以下操作:

container.RegisterType<ISpeechSynthesisService, WindowsSpeechSynthesisService>();

然后你可以直接在PCL中获取实例,例如:

var speechService = container.GetInstance<ISpeechSynthesisService>();

或者你更愿意在ViewModels或其他服务中使用构造函数注入

public MyViewModel( ISpeechSynthesisService speechService )
{
    //...
}

正如我所提到的,大多数MVVM框架都会“免费”提供这两种方法,因此您无需手动实现。

非常好的答案!非常感谢你! - Branyac
1
谢谢你的答案,它帮助我找到了一个类似的问题。我想知道为什么VS允许成功构建PCL。我以为编译器会捕捉到这个错误。 - Hong
谢谢,这帮助我解决了我的问题。我在我的PCL中也参考了Windows.winmd。 - Dave

0

这些错误让我很烦恼,因为失败的库是由VS自动添加的,而我没有注意到。一旦我弄清楚了这一点,解决就很容易了。

  1. 删除相关引用(在您的情况下是Windows.Foundation.UniversalApiContract,但错误也可能发生在不同的库中,比如在我的情况下是Windows.Phone.PhoneContract)。
  2. 关闭Visual Studio
  3. 从项目目录中删除binobj文件夹
  4. 打开项目
  5. 执行清理操作
  6. 找到刚刚删除的库的替代品(如果需要)
  7. 重新构建,应该就没问题了

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